Skip to content

fix(security): patch DOM-based XSS in bundled Featherlight (CVE-2024-5667)#80

Open
cpalexh wants to merge 3 commits into
cipherdevgroup:developfrom
cpalexh:fix/cve-2024-5667-featherlight-xss
Open

fix(security): patch DOM-based XSS in bundled Featherlight (CVE-2024-5667)#80
cpalexh wants to merge 3 commits into
cipherdevgroup:developfrom
cpalexh:fix/cve-2024-5667-featherlight-xss

Conversation

@cpalexh

@cpalexh cpalexh commented Jun 11, 2026

Copy link
Copy Markdown

Summary

Patches CVE-2024-5667 — an authenticated (Contributor+) stored DOM-based XSS via the bundled Featherlight library. Upstream Featherlight has no release that fixes this, so the bundled copy is hardened directly.

The Featherlight content filters turned attacker-controllable attribute values (href, data-featherlight) into live DOM. Three sinks are addressed:

  • image — the <img> was built by string-concatenating the URL ($('<img src="'+url+'" …/>')), allowing attribute breakout. Because the plugin auto-tags any image-extension href with data-featherlight="image", a stored href like x" onerror="alert(1)".jpg executed. Now the URL is assigned via .attr('src', url).
  • jquery$(elem) parsed selector strings containing <…> as HTML. Now resolved via $(document).find(elem), so input is only ever treated as a selector.
  • html$(html) rendered raw attacker markup. Now parsed with $.parseHTML(html, document, false) (drops <script>) and sanitized to strip inline event handlers (on*) and javascript: URLs.

Changes

  • Hardened all four served files: js/vendor/featherlight.js, js/vendor/featherlight.min.js, js/wpFeatherlight.pkgd.js, js/wpFeatherlight.pkgd.min.js (the last is the default production bundle).
  • Bumped version 1.3.41.3.5 (wp-featherlight.php, includes/class-plugin.php, readme.txt) — this also busts the script enqueue cache so clients fetch the patched JS.
  • Updated CHANGELOG.md and readme.txt.

Note for maintainers

grunt build:js copies Featherlight from node_modules/featherlight/src/ into js/vendor/ and regenerates the .pkgd bundles, so a rebuild will overwrite this patch. To keep the fix durable, the dependency itself should be patched (e.g. patch-package, a pinned fork, or a post-build step). The shipped files were edited directly since no build toolchain is required to verify the fix.

Testing

  • All four JS files compile cleanly (validated via JavaScriptCore).
  • The sanitizer logic was unit-tested: it strips onerror/onload/ONCLICK and tab-obfuscated javascript: URLs while preserving src, alt, class, safe href, and data-* attributes.

🤖 Generated with Claude Code

…5667)

Harden the Featherlight content filters so attacker-controlled attribute
values (href, data-featherlight) can no longer execute script:

- image: assign the URL via .attr('src', url) instead of concatenating it
  into markup, preventing attribute breakout
- jquery: resolve via $(document).find(elem) so strings are treated as
  selectors, never parsed as HTML
- html: sanitize parsed markup, stripping inline event handlers,
  javascript: URLs and <script> tags

Applied to all served files (vendor sources + packed bundles). Bumps
version to 1.3.5 (also busts the script enqueue cache).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cpalexh cpalexh marked this pull request as draft June 11, 2026 06:35
addCaptions() assigned caption markup via innerHTML (caption.html()),
which executes inline event handlers (e.g. <img onerror>) and other
script when a caption contains raw HTML. Parse the caption with
$.parseHTML (keepScripts=false) and strip on* handlers and javascript:
URLs before appending, matching the html content-filter hardening.

Applied to the source (assets/plugin/js) and all built/minified bundles.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cpalexh cpalexh marked this pull request as ready for review June 11, 2026 07:08
The CVE-2024-5667 content-filter hardening is retained in the packed
bundles (wpFeatherlight.pkgd[.min].js) that WordPress actually enqueues
by default. The standalone js/vendor/featherlight[.min].js copies are
restored to upstream to keep the third-party library unmodified.

Note: in SCRIPT_DEBUG/unpacked mode the unmodified vendor file loads, so
that mode is not hardened; and a grunt rebuild regenerates the bundles
from vendor and would drop the fix. Patch the dependency to make it
durable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant