in serialized function bodies","description":"### Impact\n\n`serialize-javascript` escapes its output so it is safe to embed inside a\n``\ninto the output, terminating the script element early so the remainder is\nparsed as HTML.\n\n`SCRIPT_CLOSE_REGEXP` used `<\\/script[^>]*>` as its first alternative. The\ncharacter class excludes only `>`, so a single match could run from one\n` in serialized function bodies","description":"### Impact\n\n`serialize-javascript` escapes its output so it is safe to embed inside a\n``\ninto the output, terminating the script element early so the remainder is\nparsed as HTML.\n\n`SCRIPT_CLOSE_REGEXP` used `<\\/script[^>]*>` as its first alternative. The\ncharacter class excludes only `>`, so a single match could run from one\n``\ninto the output, terminating the script element early so the remainder is\nparsed as HTML.\n\n`SCRIPT_CLOSE_REGEXP` used `<\\/script[^>]*>` as its first alternative. The\ncharacter class excludes only `>`, so a single match could run from one\n`` anywhere in the source — swallowing a\nsecond, complete `` along the way. Only "}},{"@type":"Question","name":"How severe is CVE-2026-97711?","acceptedAnswer":{"@type":"Answer","text":"No CVSS score has been assigned to CVE-2026-97711 yet. Review the advisory details and affected package list to assess your exposure."}},{"@type":"Question","name":"Which packages are affected by CVE-2026-97711?","acceptedAnswer":{"@type":"Answer","text":"CVE-2026-97711 affects the following packages: serialize-javascript (npm). Ecosystems affected: npm."}},{"@type":"Question","name":"How do I fix CVE-2026-97711?","acceptedAnswer":{"@type":"Answer","text":"Update serialize-javascript to 7.1.2 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-97711 is resolved across your whole dependency graph."}},{"@type":"Question","name":"How do I detect CVE-2026-97711 in my npm dependencies?","acceptedAnswer":{"@type":"Answer","text":"Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for serialize-javascript, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version."}},{"@type":"Question","name":"How do I mitigate CVE-2026-97711 if there is no patch (or I can't update yet)?","acceptedAnswer":{"@type":"Answer","text":"Escape or sanitise the affected output on the server side rather than relying on client-side filtering, and add a Content-Security-Policy that blocks inline script execution so injected markup cannot run even if it reaches the page."}},{"@type":"Question","name":"Is CVE-2026-97711 actively exploited in the wild?","acceptedAnswer":{"@type":"Answer","text":"No public exploit code has been indexed for CVE-2026-97711 yet. This does not mean the vulnerability cannot be exploited — absence of public exploits does not imply safety. Apply the recommended fix and use O3 Security to monitor your exposure."}},{"@type":"Question","name":"What is the EPSS score for CVE-2026-97711?","acceptedAnswer":{"@type":"Answer","text":"CVE-2026-97711 has an EPSS (Exploit Prediction Scoring System) score of 0.3%, placing it in the 22th percentile of all CVEs. EPSS is maintained by FIRST.org and estimates the probability that a vulnerability will be exploited in the wild within the next 30 days. This score indicates relatively lower exploitation probability, though the CVSS severity should still guide your patching priority."}},{"@type":"Question","name":"What type of vulnerability is CVE-2026-97711?","acceptedAnswer":{"@type":"Answer","text":"CVE-2026-97711 is classified as Cross-site Scripting (XSS) (CWE-79). This weakness type describe the underlying flaw category, which helps determine the potential impact and the right class of mitigation. This is a high-impact weakness class that often enables remote code execution or data exposure."}},{"@type":"Question","name":"When was CVE-2026-97711 published, and has it been updated?","acceptedAnswer":{"@type":"Answer","text":"CVE-2026-97711 was published on September 29, 2026 and was last updated on October 21, 2026. Advisory data evolves as severity scores, affected ranges, and exploit intelligence are revised — always check the latest version of the advisory before acting."}}]}
Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
📦 npm
Not in CISA KEV

CVE-2026-97711 — serialize-javascript

Fix: yahoo/serialize-javascript@2bdbaaf

CVE-2026-97711 is a Cross-site Scripting (XSS) vulnerability in serialize-javascript. A fix is available for serialize-javascript — see the affected versions and patch details below.

Serialize JavaScript: Cross-site scripting (XSS) via unescaped </script> in serialized function bodies

Also known asGHSA-gfhx-hw2g-v5hg
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 21, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

No confirmed exploitation observed yet

  • CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-97711.

EPSS Exploitation Probability

via FIRST.org ↗
0.3%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs22th percentile — riskier than 22% of all scored CVEsHighest risk
0.00%0.27%0.53%0.80%0.3%0.3%Oct 26Oct 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

Real-World Exposure

1 pkg affected

How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.

2Kother npm packages depend on this — each one inherits the vulnerability until it's patched upstream
serialize-javascriptnpm
26.4Mdownloads / week

Description

Impact

serialize-javascript escapes its output so it is safe to embed inside a <script> element. In 7.1.1 that guarantee does not hold for function values: a crafted function body can carry a literal, unescaped </script> into the output, terminating the script element early so the remainder is parsed as HTML.

SCRIPT_CLOSE_REGEXP used <\/script[^>]*> as its first alternative. The character class excludes only >, so a single match could run from one </script all the way to the next > anywhere in the source — swallowing a second, complete </script> along the way. Only one replacement is emitted per match, and the plain-code branch neutralizes just the leading < ('< ' + match.slice(1)), so the swallowed tag was re-emitted verbatim.

Reaching that shape requires </script in code position, which is legal JavaScript: x</script=+/ parses as x < /script=+/, a comparison against a regex literal.

const serialize = require('serialize-javascript');
const src = "function f(x){ return x</script=+/ + '</script><img src=x onerror=alert(1)>' }";
const out = serialize({ h: new Function('return ' + src)() });
// {"h":function f(x){ return x< /script=+/ + '</script><img src=x onerror=alert(1)>' }}

Embedded as the README documents (<script>window.S = <%= serialize(state) %></script>) and parsed by Chromium, the script element ends at the injected tag and the <img> becomes a live DOM node with its onerror handler executing in the page origin.

Only the function path is affected. The same payload passed as data is escaped correctly, and options.isJSON / non-function values are unaffected.

Patches

Fixed in 7.1.2. The wildcard now excludes < as well as > ([^<>]*), so a match can never reach past a second <. Every </script in the source therefore either begins its own match or is followed by a character the HTML tokenizer does not accept as ending a tag name — it ends the tag name only on TAB, LF, FF, CR, SPACE, / or >, and emits anything else as text.

Workarounds

Upgrade to 7.1.2. If you cannot upgrade, 7.1.0 and earlier are unaffected, or avoid serializing functions whose source text is attacker-influenced.

Regression note

This is a regression specific to 7.1.1, not a long-standing issue. 7.1.0 and earlier applied the same wildcard but escaped the entire match, so no tag survived. Downstream scanners defaulting to a >= 7.1.0 range would be overly broad.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
📦npmserialize-javascript≥ 7.1.1&&< 7.1.27.1.2npm install serialize-javascript@7.1.2

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for serialize-javascript, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update serialize-javascript to 7.1.2 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-97711 is resolved across your whole dependency graph.

  3. Workarounds

    Escape or sanitise the affected output on the server side rather than relying on client-side filtering, and add a Content-Security-Policy that blocks inline script execution so injected markup cannot run even if it reaches the page.

Frequently Asked Questions

### Impact `serialize-javascript` escapes its output so it is safe to embed inside a `<script>` element. In 7.1.1 that guarantee does not hold for **function values**: a crafted function body can carry a literal, unescaped `</script>` into the output, terminating the script element early so the remainder is parsed as HTML. `SCRIPT_CLOSE_REGEXP` used `<\/script[^>]*>` as its first alternative. The character class excludes only `>`, so a single match could run from one `</script` all the way to the next `>` anywhere in the source — swallowing a second, complete `</script>` along the way. Only
O3 Security · Impact-Aware SCA

Is CVE-2026-97711 in your dependencies?

Find it across npm, including transitive dependencies.

CVE-2026-97711: serialize-javascript — Fixed in 7.1.2