- A GitHub advisory says a crafted SVG can slip a javascript: link past enshrined/svg-sanitize when the cleaned SVG is placed inline in an HTML page.
- The cause is a mismatch: the sanitizer and the browser read the same text differently. The advisory rates it CVSS 6.1 and says it needs a user click.
- Teams should find where they render uploaded SVGs inline, check for a patched release, and test the output the browser will actually see.
A security check is only as good as its agreement with whatever reads the data next. If the checker and the reader disagree about what a file says, the check proves nothing. A new advisory on a widely used PHP library shows how that gap opens.
The GitHub Advisory Database published the finding on October 8, 2026. It concerns enshrined/svg-sanitize, a library that cleans SVG image files so users can upload them safely. ExPatch Security Research, credited to Denis Rostilov, reported it.
What the researchers found
The advisory says a crafted SVG can get past the library's link validation. A link starting with javascript: then comes out of the sanitizer unchanged. In a browser, clicking it runs the attacker's code in the page's own origin.
The advisory calls this a logic bug in the library. It says the flaw does not depend on a bug in PHP's ext/dom extension. It lists PHP 8.3.24 and says any PHP version is affected. The researchers confirmed the attack in Chrome 148.
How one string means two things
SVG files can carry a small header called a DTD, which lets the author define shortcuts called entities. The attacker defines an entity named Tab whose value is the single character #.
The attacker then writes a link whose address begins with 	 followed by javascript:alert(document.domain). The sanitizer reads the file as XML, so it swaps 	 for #. The address now looks like a harmless in-page anchor, because it starts with #. The check called isHrefSafeValue() returns true.
Then the library writes the file back out. Its saveXML() step keeps the 	 shortcut as written and drops the DTD that defined it. The browser never sees the definition.
When the SVG sits inline in an HTML page, the browser reads 	 by HTML5 rules. In HTML5, Tab is a built-in name for the tab character. The browser's URL parser ignores leading whitespace, so the address becomes javascript:alert(document.domain).
Think of a customs officer who inspects a parcel using one language's label. The recipient opens it using another language's dictionary. Both are reading the same words and reaching different conclusions.
The advisory adds that other HTML5 named references that expand to characters the URL parser ignores could work the same way.
Who is exposed, and who is not
Placement matters. The attack only works when the cleaned SVG is pasted into the page's own HTML. A standalone image tag pointing to an SVG file is not affected, because the browser then parses the file as XML and rejects it.
The advisory names WordPress themes that echo file contents for inline SVG as one risky pattern. It also names any application that prints sanitizer output straight into HTML.
The attack path it describes is short. An attacker uploads the SVG, for example as a WordPress Author or through any upload endpoint the library protects. The sanitizer reports no issues. A user clicks the link. The script then runs with that user's access to the page.
The advisory says that when chained with session theft or admin takeover, the effective severity is High. It lists document.cookie access and requests to /wp-admin/ as examples of what a script could do.
Why the footprint matters
The advisory lists 1.3M downloads a month and more than 90 Packagist dependents, including TYPO3 and Drupal. It also lists the WordPress Safe SVG plugin, with more than 1M active installs, because of themes that render SVG inline.
Those figures show how many projects pull in the library. They do not show how many render SVGs inline in the way that creates the risk. That distinction is the first thing a team should settle for itself.
What leaders should ask
The lesson is that approving a file and safely displaying it are separate jobs. A sanitizer can pass its own tests and still hand the browser something different from what it checked.
The advisory offers three fixes. Option 1, which it recommends, strips the DOCTYPE before parsing, so no entity definitions exist and no collision can occur. Option 2 validates links again after the file is serialized. Option 3 expands entities before validation.
The advisory text names no patched release. It links to the project's releases page, at a tag labelled 1.0.0, but does not say that release is the fix. Check the project's releases directly and confirm which version carries a correction.
Put these questions to your engineering team:
Where do we accept SVG uploads, and who can upload? Which pages print those files inline rather than as images? Does any dependency, plugin or theme use svg-sanitize, and has it been updated? Do our tests check the final output the browser receives, or only the sanitizer's verdict?
Until a fix is confirmed, serving uploaded SVGs as images instead of inline avoids the path the advisory describes. A defence that checks one version of the data and ships another is only half a defence.
Produced by the WebPulse Newsroom with AI assistance from the original reporting credited below, and checked against that source by our editorial review. How we use AI.
Original reporting: GitHub Advisory Database.





