Make WordPress Core

Opened 17 hours ago

Last modified 17 hours ago

#66265 new enhancement

Administration: Avoid $() for selecting with non-literal selectors

Reported by: jonsurrell Owned by:
Priority: normal Milestone: 7.2
Component: Administration Version:
Severity: normal Keywords: has-patch
Cc: Focuses: javascript

Description

$( string ) both selects and parses HTML: a string that starts with < creates elements instead of selecting them. When the selector is not a string literal, for example a link href, location.hash, or a value read from the DOM, the caller decides which of the two happens. Escaping it does not help either: a value concatenated into a selector can change what the selector matches.

Prefer $( document ).find( selector ), or a narrower context, which only selects, and escape values interpolated into selectors with $.escapeSelector(). r64133 made this change for the contextual help tabs in common.js; this ticket covers the remaining instances in admin scripts.

Change History (1)

This ticket was mentioned in ​PR #14061 on ​WordPress/wordpress-develop by ​@jonsurrell.


17 hours ago
#1

  • Keywords has-patch added

Several admin scripts pass a link href or the URL hash to $(), which parses strings that look like HTML as markup. This changes each to treat the value only as a selector:

  • link.js and post.js (category and taxonomy tabs) pass the tab link's href, and site-health.js passes window.location.hash. The whole value is the selector, so these select through $( document ).find(), which never parses HTML. Escaping would not work here: $.escapeSelector( '#categories-all' ) escapes the # and matches nothing.
  • plugin-install.js builds '#section-' + tab from a section name in the plugin information response. The literal prefix already keeps $() from parsing HTML, so the value is wrapped in $.escapeSelector() to keep selector punctuation in a section name from changing the match. Core bundles jQuery 3.7.1; $.escapeSelector() was added in 3.0.

None of these is known to be exploitable. r64133 made the same change to the contextual help tabs in common.js.

No QUnit tests cover these scripts. JSHint passes on the four files with the options the Gruntfile applies to them.

Trac ticket: https://core.trac.wordpress.org/ticket/66265

Use of AI Tools

AI assistance: Yes
Tools: Claude Code
Models: Claude Opus 5.5
Used for: Applying the change, checking the touched files for similar selections, running lint, and drafting this description.

Note: See TracTickets for help on using tickets.