fix(removeScriptElement): backport security hardening to v2 - #2272
Merged
Merged
Conversation
This was referenced Sep 4, 2026
nschloe
pushed a commit
to live-clones/forgejo
that referenced
this pull request
Sep 9, 2026
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [svgo](https://svgo.dev) ([source](https://github.com/svg/svgo)) | [`4.0.2` → `4.1.0`](https://renovatebot.com/diffs/npm/svgo/4.0.2/4.1.0) |  |  | --- ### SVGO: removeScripts incompletely sanitizes executable HTML in SVG foreignObject elements [CVE-2026-84369](https://nvd.nist.gov/vuln/detail/CVE-2026-84369) / [GHSA-4vpr-x523-8j87](GHSA-4vpr-x523-8j87) <details> <summary>More information</summary> #### Details ##### Summary SVGO's opt-in `removeScripts` plugin did not inspect executable HTML content inside SVG `<foreignObject>` elements. Applications that used this plugin as their only protection for untrusted SVG input could produce SVGs containing active HTML and expose users to cross-site scripting (XSS). SVGO is an optimizer rather than a comprehensive sanitization library, but `removeScripts` is maintained for consumers that already rely on it to remove common script execution paths. ##### Details Although the plugin removed SVG and XHTML `<script>` elements, it left other HTML execution paths inside `<foreignObject>` unchanged. These included: - event-handler attributes such as `onload` and `onbeforetoggle`; - `srcdoc` documents, including on `<iframe>` elements; - executable URLs in HTML attributes such as `action`, `data`, `formaction`, `href`, and `src`. An attacker could place one of these payloads in an SVG. If an application optimized the untrusted SVG with `removeScripts` and then served the result in an active browser context, the payload could execute in the viewer's origin. ##### Impact Successful exploitation could allow script execution in the context where the optimized SVG is rendered. Depending on the embedding and origin configuration, this could expose cookies or local storage, modify content, or perform actions as the victim. The plugin is opt-in, so consumers that do not enable `removeScripts` are not relying on the affected behavior. Typical local optimization of trusted SVG files is not affected. ##### Patches Upgrade to one of the following releases for the maintained release line in use: | Release line | Patched version | Plugin | | --- | --- | --- | | v2 | 2.8.4 | `removeScriptElement` | | v3 | 3.3.5 | `removeScriptElement` | | v4 | 4.1.0 | `removeScripts` | The fix preserves visual HTML inside SVG `<foreignObject>` elements while removing event attributes, `srcdoc`, and executable URL values from active HTML URL attributes. SVGO v1 is no longer maintained. Users of v1 should upgrade to a supported release line. ##### Workarounds For hostile input, use a dedicated SVG sanitization tool before passing the SVG to SVGO. As defense in depth, applications can reject or remove `<foreignObject>` content and avoid serving user-controlled SVGs in an active same-origin context. #### Severity - CVSS Score: 6.1 / 10 (Medium) - Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N` #### References - [https://github.com/svg/svgo/security/advisories/GHSA-4vpr-x523-8j87](https://github.com/svg/svgo/security/advisories/GHSA-4vpr-x523-8j87) - [https://nvd.nist.gov/vuln/detail/CVE-2026-84369](https://nvd.nist.gov/vuln/detail/CVE-2026-84369) - [https://github.com/svg/svgo/pull/2264](https://github.com/svg/svgo/pull/2264) - [https://github.com/svg/svgo/pull/2269](https://github.com/svg/svgo/pull/2269) - [https://github.com/svg/svgo/pull/2272](https://github.com/svg/svgo/pull/2272) - [https://github.com/svg/svgo/commit/0557385564a5c6c11d76cd934a6cff94451e532c](https://github.com/svg/svgo/commit/0557385564a5c6c11d76cd934a6cff94451e532c) - [https://github.com/svg/svgo/commit/994a9f00d79ddec68ce19a1ce9eb8ca08d747e4f](https://github.com/svg/svgo/commit/994a9f00d79ddec68ce19a1ce9eb8ca08d747e4f) - [https://github.com/svg/svgo/commit/fd51e474a300417d9361d9302d596b1763146327](https://github.com/svg/svgo/commit/fd51e474a300417d9361d9302d596b1763146327) - [https://github.com/svg/svgo](https://github.com/svg/svgo) - [https://github.com/svg/svgo/releases/tag/v2.8.4](https://github.com/svg/svgo/releases/tag/v2.8.4) - [https://github.com/svg/svgo/releases/tag/v3.3.5](https://github.com/svg/svgo/releases/tag/v3.3.5) - [https://github.com/svg/svgo/releases/tag/v4.1.0](https://github.com/svg/svgo/releases/tag/v4.1.0) This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-4vpr-x523-8j87) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### SVGO: removeScripts allows executable links through namespace and control-character bypasses [CVE-2026-84370](https://nvd.nist.gov/vuln/detail/CVE-2026-84370) / [GHSA-w27v-7q3p-w38r](GHSA-w27v-7q3p-w38r) <details> <summary>More information</summary> #### Details ##### Summary SVGO's opt-in `removeScripts` plugin failed to remove some executable links. Namespace-prefixed SVG anchors and URL schemes containing ASCII tabs or newlines could bypass its checks. Applications that used this plugin as their only protection for untrusted SVG input could expose users to cross-site scripting (XSS). SVGO is an optimizer rather than a comprehensive sanitization library, but `removeScripts` is maintained for consumers that already rely on it to remove common script execution paths. ##### Details Two related bypasses were present: 1. The plugin inspected unprefixed SVG `<a>` elements but did not recognize namespace-prefixed SVG anchors such as `<svg:a>` when the prefix was bound to the SVG namespace. Their executable `href` or namespaced `*:href` values remained intact. 2. The URL check did not account for ASCII tab, line-feed, or carriage-return characters embedded in a scheme. Browsers remove these characters before parsing the scheme, so values such as `java&#​9;script:` could remain executable after bypassing the plugin's `javascript:` check. Anchors in unrelated custom namespaces are not executable SVG anchors and remain untouched. ##### Impact If an application optimized attacker-controlled SVGs with `removeScripts` and then served the result in an active browser context, a victim could follow a link that executes script in the SVG's origin. Depending on the embedding and origin configuration, this could expose cookies or local storage, modify content, or perform actions as the victim. The plugin is opt-in, so consumers that do not enable it are not relying on the affected behavior. Typical local optimization of trusted SVG files is not affected. ##### Patches Upgrade to one of the following releases for the maintained release line in use: | Release line | Patched version | Plugin | | --- | --- | --- | | v2 | 2.8.4 | `removeScriptElement` | | v3 | 3.3.5 | `removeScriptElement` | | v4 | 4.1.0 | `removeScripts` | The fix makes SVG anchor handling namespace-aware and strips ASCII tabs, line feeds, and carriage returns before checking executable URL schemes. SVGO v1 is no longer maintained. Users of v1 should upgrade to a supported release line. ##### Workarounds For hostile input, use a dedicated SVG sanitization tool before passing the SVG to SVGO. Applications can also reject links from untrusted SVG input and avoid serving user-controlled SVGs in an active same-origin context. ##### References - v4 fix: svg/svgo#2268 - related executable URL hardening: svg/svgo#2263 - v3 backport: svg/svgo#2269 - v2 backport: svg/svgo#2272 - v4.1.0 release: https://github.com/svg/svgo/releases/tag/v4.1.0 - v3.3.5 release: https://github.com/svg/svgo/releases/tag/v3.3.5 - v2.8.4 release: https://github.com/svg/svgo/releases/tag/v2.8.4 #### Severity - CVSS Score: 8.2 / 10 (High) - Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N` #### References - [https://github.com/svg/svgo/security/advisories/GHSA-w27v-7q3p-w38r](https://github.com/svg/svgo/security/advisories/GHSA-w27v-7q3p-w38r) - [https://nvd.nist.gov/vuln/detail/CVE-2026-84370](https://nvd.nist.gov/vuln/detail/CVE-2026-84370) - [https://github.com/svg/svgo/pull/2268](https://github.com/svg/svgo/pull/2268) - [https://github.com/svg/svgo/pull/2269](https://github.com/svg/svgo/pull/2269) - [https://github.com/svg/svgo/pull/2272](https://github.com/svg/svgo/pull/2272) - [https://github.com/svg/svgo/commit/0557385564a5c6c11d76cd934a6cff94451e532c](https://github.com/svg/svgo/commit/0557385564a5c6c11d76cd934a6cff94451e532c) - [https://github.com/svg/svgo/commit/3db3ef33e409a0bc0fdaf255e46c908b00e93bc2](https://github.com/svg/svgo/commit/3db3ef33e409a0bc0fdaf255e46c908b00e93bc2) - [https://github.com/svg/svgo/commit/994a9f00d79ddec68ce19a1ce9eb8ca08d747e4f](https://github.com/svg/svgo/commit/994a9f00d79ddec68ce19a1ce9eb8ca08d747e4f) - [https://github.com/svg/svgo](https://github.com/svg/svgo) - [https://github.com/svg/svgo/releases/tag/v2.8.4](https://github.com/svg/svgo/releases/tag/v2.8.4) - [https://github.com/svg/svgo/releases/tag/v3.3.5](https://github.com/svg/svgo/releases/tag/v3.3.5) - [https://github.com/svg/svgo/releases/tag/v4.1.0](https://github.com/svg/svgo/releases/tag/v4.1.0) This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-w27v-7q3p-w38r) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### Release Notes <details> <summary>svg/svgo (svgo)</summary> ### [`v4.1.0`](https://github.com/svg/svgo/releases/tag/v4.1.0) [Compare Source](svg/svgo@v4.0.2...v4.1.0) This minor release upgrades the SAX parser and introduces stricter XML validation. It also includes important security hardening for `removeScripts`, dependency updates, and improvements to the test and regression infrastructure. ##### Support SVGO If SVGO is valuable to you or your organization, please consider [supporting the project on OpenCollective](https://opencollective.com/svgo). Your sponsorship helps fund ongoing maintenance and security work. ##### Stricter XML validation SVGO now uses [`sax` 1.6.1](https://www.npmjs.com/package/sax), upgraded from 1.5.0 ([#​2257](svg/svgo#2257)). The new parser version validates numeric character references against the ranges permitted by XML. Invalid references are now rejected in both text and attributes, including: - disallowed control characters such as `&#​1;`, ``, and ``; - UTF-16 surrogate code points such as `�`; - invalid XML code points such as ``. Valid boundary values—including `U+0020`, `U+D7FF`, `U+E000`, `U+FFFD`, and characters through `U+10FFFF`—remain supported. Parser failures are consistently exposed as `SvgoParserError` errors with an `Invalid character entity` reason. This is an intentional behavior change: malformed SVGs that were previously accepted may now produce a parser error, while valid XML documents are unaffected. ##### Security The [`removeScripts`](https://svgo.dev/docs/plugins/removeScripts/) plugin has been hardened against several script-execution bypasses: - Filters executable `data:` URLs containing HTML, XHTML, or SVG documents while preserving inert data such as PNG images, and filters legacy `vbscript:` URLs ([#​2263](svg/svgo#2263)). - Sanitizes content inside SVG `<foreignObject>` elements by removing HTML event-handler attributes, `srcdoc`, and executable URLs from `action`, `data`, `formaction`, `href`, and `src`, while preserving non-executable HTML and visual content ([#​2264](svg/svgo#2264)). - Recognizes namespace-prefixed SVG `<a>` elements and removes ASCII tabs and newlines before checking URL schemes, preventing values such as `java&#​9;script:` from bypassing detection while preserving elements in unrelated custom namespaces ([#​2268](svg/svgo#2268)). These changes address: - [GHSA-4vpr-x523-8j87](GHSA-4vpr-x523-8j87) - [GHSA-w27v-7q3p-w38r](GHSA-w27v-7q3p-w38r) ##### Dependencies - Upgraded `css-select` to v6 and `css-what` to v7, and updated SVGO's custom selector adapter for `css-select` v6 ([#​2244](svg/svgo#2244)). ##### Project maintenance [@​TrySound](https://github.com/TrySound) is back as an active SVGO maintainer. Many thanks to [@​KTibow](https://github.com/KTibow), [@​SethFalco](https://github.com/SethFalco), and [@​XhmikosR](https://github.com/XhmikosR) for maintaining and improving SVGO over the past several years. **Full Changelog:** <svg/svgo@v4.0.2...v4.1.0> </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - Between 12:00 AM and 03:59 AM (`* 0-3 * * *`) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC42NS41IiwidXBkYXRlZEluVmVyIjoiNDQuNjUuNSIsInRhcmdldEJyYW5jaCI6InYxNS4wL2Zvcmdlam8iLCJsYWJlbHMiOlsiZGVwZW5kZW5jeS11cGdyYWRlIiwidGVzdC9ub3QtbmVlZGVkIl19--> Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/14293 Reviewed-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org>
This was referenced Sep 14, 2026
meta-codesync Bot
pushed a commit
to facebook/memlab
that referenced
this pull request
Sep 21, 2026
Summary: Bumps [[ https://github.com/svg/svgo | svgo ]] from 2.8.3 to 2.8.4 in the memlab `website` package. This is a security-only patch release on the SVGO v2 line. == Security == Backports the `removeScriptElement` hardening from SVGO v4 ([[ svg/svgo#2272 | svg/svgo#2272 ]]): - remove known SVG event attributes - reject executable `data:` URLs and legacy `vbscript:` URLs - sanitize executable HTML inside `<foreignObject>` elements - handle namespace-prefixed SVG anchors, and URL schemes containing ASCII tabs or newlines This addresses [[ GHSA-4vpr-x523-8j87 | GHSA-4vpr-x523-8j87 ]] and [[ GHSA-w27v-7q3p-w38r | GHSA-w27v-7q3p-w38r ]] for the v2 release line. Upstream notes that SVGO v2 is not officially supported and recommends migrating to v4 ([[ https://svgo.dev/docs/migrations/migration-from-v2-to-v3/ | v2 to v3 ]], [[ https://svgo.dev/docs/migrations/migration-from-v3-to-v4/ | v3 to v4 ]]); this fix was backported, but further backports are not guaranteed. == Commits == - [[ svg/svgo@0557385 | 0557385 ]] fix(removeScriptElement): backport security hardening to v2 ([[ svg/svgo#2272 | #2272 ]]) - [[ svg/svgo@0fc2b43 | 0fc2b43 ]] chore: prepare v2.8.4 release ([[ svg/svgo#2273 | #2273 ]]) - [[ svg/svgo@db45bb5 | db45bb5 ]] ci: build v2 releases with Node.js 16 ([[ svg/svgo#2274 | #2274 ]]) [[ svg/svgo@v2.8.3...v2.8.4 | Full compare view: v2.8.3...v2.8.4 ]] Maintainer change: this version was pushed to npm by GitHub Actions, a new releaser for `svgo` since the currently pinned version. Pull Request resolved: #152 Differential Revision: D121035392 Pulled By: JacksonGL fbshipit-source-id: c74c65841c1c8cde4ecd079441a9c08ec1234dcd
This was referenced Sep 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Backport the
removeScriptssecurity hardening to v2'sremoveScriptElementplugin:javascript:, legacyvbscript:, and executabledata:links while preserving inert data URLssrcdoc, and executable URL attributes inside SVGforeignObjectelementsThis backports the fixes from #2263, #2264, #2268, and #2269 and addresses GHSA-4vpr-x523-8j87 and GHSA-w27v-7q3p-w38r for the v2 release line.
Validation
yarn test— 439 passed, 3 skippedyarn lintyarn typecheckgit diff --check