{"schema":"threatline.record/2","record":{"id":"CVE-2026-115897","aliases":["GHSA-m5mm-p8h7-m29v"],"summary":"Serialize JavaScript: Cross-site scripting (XSS) via unescaped </script at the end of a serialized function body","details":"### Impact\n\n`serialize-javascript` escapes its output so it is safe to embed inside a\n`<script>` element. Before 7.1.3 that guarantee did not hold for a **function\nvalue whose source ends in a bare `</script`**.\n\nEach function body is escaped on its own, and a bare `</script` was only\nneutralized when followed — within the same body — by a character the HTML\ntokenizer treats as ending the tag name (TAB, LF, FF, CR, SPACE, `/` or `>`).\nA body ending exactly at `</script` has no following character, so it was\nemitted unescaped. The delimiter is then supplied by the surrounding output\n(for example the newline the `space` option emits after the value), and a\nlater serialized value can supply the closing `>` followed by markup:\n\n```js\nconst serialize = require('serialize-javascript');\nfunction f() {} f.toString = () => 'function f(){ return 1 }//</script';\nfunction g() {} g.toString = () => 'function g(x){ return x } > <img src=x onerror=alert(1)>';\nserialize({ a: { f }, g }, { space: 2 });\n// {\n//   \"a\": {\n//     \"f\": function f(){ return 1 }//</script\n//   },\n//   \"g\": function g(x){ return x } > <img src=x onerror=alert(1)>\n// }\n```\n\nEmbedded in a `<script>` element, the script ends at the injected tag and the\n`<img>` becomes a live element in the page.\n\nExploitation requires an attacker to control the **source text** of a\nserialized function, in practice through a spoofed `toString()`. Real\nfunctions always end in `}`, so ordinary function values are not affected,\nand non-function values (including strings containing `</script`) are\nescaped correctly.\n\n### Patches\n\nFixed in **7.1.3** (#235). The bare `</script` form is now also matched at\nthe end of the function body, so it is escaped regardless of what follows it\nin the output.\n\n### Workarounds\n\nUpgrade to **7.1.3**. If you cannot upgrade, do not serialize function values\nwhose source text (or `toString()`) can be influenced by an attacker.\n\n### Credits\n\nReported by **ha_kr25** via the Yahoo bug bounty program.","categories":["Libraries & packages"],"product":"serialize-javascript","vendor":"yahoo","ecosystem":"npm","affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-m5mm-p8h7-m29v","source_modified_at":"2026-10-23T22:09:53Z","fetched_at":"2026-10-24T00:31:04.721601Z","package":{"ecosystem":"npm","name":"serialize-javascript"},"range":"< 7.1.3"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-115897","source_modified_at":"2026-10-23T21:37:41.097Z","fetched_at":"2026-10-23T21:47:51.402276Z","product":"serialize-javascript","vendor":"yahoo","versions":[{"status":"affected","version":"< 7.1.3"}],"defaultStatus":null},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-m5mm-p8h7-m29v","source_modified_at":"2026-10-23T22:30:04.106108556Z","fetched_at":"2026-10-24T00:31:04.721601Z","package":{"ecosystem":"npm","name":"serialize-javascript","purl":"pkg:npm/serialize-javascript"},"ranges":[{"events":[{"introduced":"0"},{"fixed":"7.1.3"}],"type":"SEMVER"}],"versions":[]}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-m5mm-p8h7-m29v","source_modified_at":"2026-10-23T22:09:53Z","fetched_at":"2026-10-24T00:31:04.721601Z","package":{"ecosystem":"npm","name":"serialize-javascript"},"version":"7.1.3"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-m5mm-p8h7-m29v","source_modified_at":"2026-10-23T22:30:04.106108556Z","fetched_at":"2026-10-24T00:31:04.721601Z","package":{"ecosystem":"npm","name":"serialize-javascript","purl":"pkg:npm/serialize-javascript"},"version":"7.1.3"}],"cvss":2.1,"severity":"Low","kev":{"listed":false},"epss":{"probability":0.00394,"percentile":0.32502,"score_date":"2026-10-24"},"published_at":"2026-10-23T21:37:41.097Z","modified_at":"2026-10-23T22:30:04.106108556Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/advisories/GHSA-m5mm-p8h7-m29v","fetched_at":"2026-10-24T00:31:04.721601Z","source_modified_at":"2026-10-23T22:09:53Z"},{"source":"CVE List","url":"https://www.cve.org/CVERecord?id=CVE-2026-115897","fetched_at":"2026-10-23T21:47:51.402276Z","source_modified_at":"2026-10-23T21:37:41.097Z"},{"source":"OSV","url":"https://osv.dev/vulnerability/GHSA-m5mm-p8h7-m29v","fetched_at":"2026-10-24T00:31:04.721601Z","source_modified_at":"2026-10-23T22:30:04.106108556Z"},{"source":"EPSS","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-115897","fetched_at":"2026-10-24T18:03:20.872036Z","source_modified_at":"2026-10-24"}],"sources":["GitHub Advisory Database","CVE List","OSV","EPSS"],"references":[{"source":"CVE List","url":"https://github.com/yahoo/serialize-javascript/security/advisories/GHSA-m5mm-p8h7-m29v","tags":["x_refsource_CONFIRM"]},{"source":"CVE List","url":"https://github.com/yahoo/serialize-javascript/pull/235","tags":["x_refsource_MISC"]},{"source":"CVE List","url":"https://github.com/yahoo/serialize-javascript/commit/2864b3c6260a3bfd52d2db3e70d1a079de108a61","tags":["x_refsource_MISC"]},{"source":"CVE List","url":"https://github.com/yahoo/serialize-javascript/releases/tag/v7.1.3","tags":["x_refsource_MISC"]},{"url":"https://github.com/advisories/GHSA-m5mm-p8h7-m29v","source":"GitHub Advisory Database"}],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"cve_state":"PUBLISHED","classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":"product","confidence":"heuristic","reviewed":false},"change_timestamp":"2026-10-23T22:30:04.106108556Z","content_hash":"246e5ac808a46a066340742bd43788ac5656e8613d4888d6bc5b8e19767c4557"}}
