CWE-80
AllowedImproper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS)
Abstraction: Variant · Status: Incomplete
The product receives input from an upstream component, but it does not neutralize or incorrectly neutralizes special characters such as "<", ">", and "&" that could be interpreted as web-scripting elements when they are sent to a downstream component that processes web pages.
1041 vulnerabilities reference this CWE, most recent first.
GHSA-G3HF-77HR-RVCR
Vulnerability from github – Published: 2026-06-25 15:32 – Updated: 2026-06-25 15:32Malicious HTML content could be injected into the email address of an order, which pretix showed without sanitization on the confirmation page for individual tickets in that order.
{
"affected": [],
"aliases": [
"CVE-2026-13225"
],
"database_specific": {
"cwe_ids": [
"CWE-80"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-06-25T15:16:34Z",
"severity": "MODERATE"
},
"details": "Malicious HTML content could be injected into the email address of an \norder, which pretix showed without sanitization on the confirmation page\n for individual tickets in that order.",
"id": "GHSA-g3hf-77hr-rvcr",
"modified": "2026-06-25T15:32:02Z",
"published": "2026-06-25T15:32:02Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-13225"
},
{
"type": "WEB",
"url": "https://pretix.eu/about/en/blog/20260625-release-2026-5-2"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:L/VI:L/VA:L/SC:L/SI:L/SA:L/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-G485-8J3V-P6X8
Vulnerability from github – Published: 2026-05-05 18:28 – Updated: 2026-05-05 18:28Summary
Anonymous GitHub fetches repository content (e.g., markdown files) from GitHub's API and renders it without sanitization. On the client side, markdown is parsed with marked (with sanitize: false) and injected into the DOM via $sce.trustAsHtml() + ng-bind-html, bypassing AngularJS's built-in XSS protection. An attacker can craft a malicious GitHub repository whose README executes arbitrary JavaScript in the Anonymous GitHub origin.
Details
README fetched from GitHub API
The server fetches the README via GitHub's REST API and stores the raw markdown in MongoDB:
// https://github.com/tdurieux/anonymous_github/blob/b2d77faa6c6f35ad9ae6ed46e3a3fa4681ac84c2/src/core/source/GitHubRepository.ts#L162-L174
const ghRes = await oct.repos.getReadme({
owner: this.owner,
repo: this.repo,
ref: selected?.commit,
});
const readme = Buffer.from(
ghRes.data.content,
ghRes.data.encoding as BufferEncoding
).toString("utf-8");
selected.readme = readme;
await model.save();
It is then served to the client with no sanitization:
// https://github.com/tdurieux/anonymous_github/blob/b2d77faa6c6f35ad9ae6ed46e3a3fa4681ac84c2/src/server/routes/repository-private.ts#L254-L260
return res.send(
await repo.readme({
accessToken: token,
force: req.query.force == "1",
branch: req.query.branch as string,
})
);
Client-side rendering via $sce.trustAsHtml() + ng-bind-html
The client fetches the raw README, parses it with renderMD() (which uses marked with sanitize: false), then bypasses AngularJS sanitization:
// https://github.com/tdurieux/anonymous_github/blob/b2d77faa6c6f35ad9ae6ed46e3a3fa4681ac84c2/public/script/app.js#L1219-L1226
const res = await $http.get(`/api/repo/${o.owner}/${o.repo}/readme`, {
params: { force: force === true ? "1" : "0", branch: $scope.source.branch },
});
$scope.readme = res.data;
// https://github.com/tdurieux/anonymous_github/blob/b2d77faa6c6f35ad9ae6ed46e3a3fa4681ac84c2/public/script/app.js#L1339-L1343
const html = renderMD(
$scope.anonymize_readme,
`https://github.com/${o.owner}/${o.repo}/raw/${$scope.source.branch}/`
);
$scope.html_readme = $sce.trustAsHtml(html); // sink: bypasses Angular XSS protection
The renderMD() function explicitly disables sanitization:
// https://github.com/tdurieux/anonymous_github/blob/b2d77faa6c6f35ad9ae6ed46e3a3fa4681ac84c2/public/script/utils.js#L165-L176
marked.setOptions({
sanitize: false, // HTML in markdown is preserved as-is
// ...
});
return marked.parse(md, { renderer });
The resulting HTML is bound to the DOM via ng-bind-html, which trusts the string marked by $sce.trustAsHtml() and inserts it as innerHTML.
Impact
- Stored XSS: Any malicious GitHub repository can execute JavaScript in the Anonymous GitHub origin when a user anonymizes it or views its content
- Account Takeover: Steal authentication tokens and session cookies
- Data Exfiltration: Access other users' anonymization configurations and private repository data via
/api/userand/api/repo/list
Proof of Concept
- Create a GitHub repository with a malicious
README.md:
# Innocent README
<img src=x onerror="alert(document.domain)">
- On Anonymous GitHub, enter the malicious repository URL to anonymize it
- The XSS executes immediately when the README preview is rendered on the anonymize page
Remediation
- Sanitize markdown output with DOMPurify before rendering (the dependency already exists but is unused)
- Serve HTML files with
Content-Disposition: attachmentor in a sandboxed iframe on a separate origin - Replace
$sce.trustAsHtml()with properngSanitizeusage - HTML-escape filenames and paths in directory listing templates
- Add Content Security Policy headers
Credits
Zhengyu Liu, Jingcheng Yang
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "@tdurieux/anonymous_github"
},
"ranges": [
{
"events": [
{
"introduced": "2.2.0"
},
{
"fixed": "2.3.0"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"2.2.0"
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-79",
"CWE-80"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-05T18:28:32Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\n\nAnonymous GitHub fetches repository content (e.g., markdown files) from GitHub\u0027s API and renders it without sanitization. On the client side, markdown is parsed with `marked` (with `sanitize: false`) and injected into the DOM via `$sce.trustAsHtml()` + `ng-bind-html`, bypassing AngularJS\u0027s built-in XSS protection. An attacker can craft a malicious GitHub repository whose README executes arbitrary JavaScript in the Anonymous GitHub origin.\n\n### Details\n\n#### README fetched from GitHub API\n\nThe server fetches the README via GitHub\u0027s REST API and stores the raw markdown in MongoDB:\n\n```typescript\n// https://github.com/tdurieux/anonymous_github/blob/b2d77faa6c6f35ad9ae6ed46e3a3fa4681ac84c2/src/core/source/GitHubRepository.ts#L162-L174\nconst ghRes = await oct.repos.getReadme({\n owner: this.owner,\n repo: this.repo,\n ref: selected?.commit,\n});\nconst readme = Buffer.from(\n ghRes.data.content,\n ghRes.data.encoding as BufferEncoding\n).toString(\"utf-8\");\nselected.readme = readme;\nawait model.save();\n```\n\nIt is then served to the client with no sanitization:\n\n```typescript\n// https://github.com/tdurieux/anonymous_github/blob/b2d77faa6c6f35ad9ae6ed46e3a3fa4681ac84c2/src/server/routes/repository-private.ts#L254-L260\nreturn res.send(\n await repo.readme({\n accessToken: token,\n force: req.query.force == \"1\",\n branch: req.query.branch as string,\n })\n);\n```\n\n#### Client-side rendering via `$sce.trustAsHtml()` + `ng-bind-html`\n\nThe client fetches the raw README, parses it with `renderMD()` (which uses `marked` with `sanitize: false`), then bypasses AngularJS sanitization:\n\n```javascript\n// https://github.com/tdurieux/anonymous_github/blob/b2d77faa6c6f35ad9ae6ed46e3a3fa4681ac84c2/public/script/app.js#L1219-L1226\nconst res = await $http.get(`/api/repo/${o.owner}/${o.repo}/readme`, {\n params: { force: force === true ? \"1\" : \"0\", branch: $scope.source.branch },\n});\n$scope.readme = res.data;\n```\n\n```javascript\n// https://github.com/tdurieux/anonymous_github/blob/b2d77faa6c6f35ad9ae6ed46e3a3fa4681ac84c2/public/script/app.js#L1339-L1343\nconst html = renderMD(\n $scope.anonymize_readme,\n `https://github.com/${o.owner}/${o.repo}/raw/${$scope.source.branch}/`\n);\n$scope.html_readme = $sce.trustAsHtml(html); // sink: bypasses Angular XSS protection\n```\n\nThe `renderMD()` function explicitly disables sanitization:\n\n```javascript\n// https://github.com/tdurieux/anonymous_github/blob/b2d77faa6c6f35ad9ae6ed46e3a3fa4681ac84c2/public/script/utils.js#L165-L176\nmarked.setOptions({\n sanitize: false, // HTML in markdown is preserved as-is\n // ...\n});\nreturn marked.parse(md, { renderer });\n```\n\nThe resulting HTML is bound to the DOM via `ng-bind-html`, which trusts the string marked by `$sce.trustAsHtml()` and inserts it as innerHTML.\n\n### Impact\n\n1. **Stored XSS**: Any malicious GitHub repository can execute JavaScript in the Anonymous GitHub origin when a user anonymizes it or views its content\n2. **Account Takeover**: Steal authentication tokens and session cookies\n3. **Data Exfiltration**: Access other users\u0027 anonymization configurations and private repository data via `/api/user` and `/api/repo/list`\n\n### Proof of Concept\n\n\n\n1. Create a GitHub repository with a malicious `README.md`:\n\n```markdown\n# Innocent README\n\u003cimg src=x onerror=\"alert(document.domain)\"\u003e\n```\n\n2. On Anonymous GitHub, enter the malicious repository URL to anonymize it\n3. The XSS executes immediately when the README preview is rendered on the anonymize page\n\n### Remediation\n\n1. Sanitize markdown output with DOMPurify before rendering (the dependency already exists but is unused)\n2. Serve HTML files with `Content-Disposition: attachment` or in a sandboxed iframe on a separate origin\n3. Replace `$sce.trustAsHtml()` with proper `ngSanitize` usage\n4. HTML-escape filenames and paths in directory listing templates\n5. Add Content Security Policy headers\n\n### Credits\n\nZhengyu Liu, Jingcheng Yang",
"id": "GHSA-g485-8j3v-p6x8",
"modified": "2026-05-05T18:28:32Z",
"published": "2026-05-05T18:28:32Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/tdurieux/anonymous_github/security/advisories/GHSA-g485-8j3v-p6x8"
},
{
"type": "PACKAGE",
"url": "https://github.com/tdurieux/anonymous_github"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "@tdurieux/anonymous_github Vulnerable to XSS via Unsanitized GitHub Repository Content Rendering in Anonymous GitHub Origin"
}
GHSA-G496-V2VQ-M798
Vulnerability from github – Published: 2026-04-08 09:31 – Updated: 2026-04-09 21:31Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS) vulnerability in kutethemes Uminex uminex allows Code Injection.This issue affects Uminex: from n/a through <= 1.0.9.
{
"affected": [],
"aliases": [
"CVE-2026-39629"
],
"database_specific": {
"cwe_ids": [
"CWE-80"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-04-08T09:16:33Z",
"severity": "MODERATE"
},
"details": "Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS) vulnerability in kutethemes Uminex uminex allows Code Injection.This issue affects Uminex: from n/a through \u003c= 1.0.9.",
"id": "GHSA-g496-v2vq-m798",
"modified": "2026-04-09T21:31:28Z",
"published": "2026-04-08T09:31:34Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-39629"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/Wordpress/Theme/uminex/vulnerability/wordpress-uminex-theme-1-0-9-arbitrary-shortcode-execution-vulnerability?_s_id=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-G5GQ-RQ8M-786Q
Vulnerability from github – Published: 2025-09-30 12:30 – Updated: 2025-09-30 12:30The Eulerpool Research Systems plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin's 'aaq' shortcode in all versions up to, and including, 4.0.1 due to insufficient input sanitization and output escaping on user supplied attributes. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
{
"affected": [],
"aliases": [
"CVE-2025-10128"
],
"database_specific": {
"cwe_ids": [
"CWE-80"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-09-30T11:37:37Z",
"severity": "MODERATE"
},
"details": "The Eulerpool Research Systems plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin\u0027s \u0027aaq\u0027 shortcode in all versions up to, and including, 4.0.1 due to insufficient input sanitization and output escaping on user supplied attributes. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.",
"id": "GHSA-g5gq-rq8m-786q",
"modified": "2025-09-30T12:30:51Z",
"published": "2025-09-30T12:30:51Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-10128"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/alleaktien-quantitativ/trunk/aaq-fundamentals-plugin.php#L36"
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/e0b4267b-2929-489b-86b8-cd256708c5bd?source=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-G5H8-25HR-RHCH
Vulnerability from github – Published: 2024-05-17 09:31 – Updated: 2024-05-17 09:31Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS) vulnerability in CodePeople CP Polls allows Code Injection.This issue affects CP Polls: from n/a through 1.0.71.
{
"affected": [],
"aliases": [
"CVE-2024-24874"
],
"database_specific": {
"cwe_ids": [
"CWE-80"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-05-17T09:15:24Z",
"severity": "MODERATE"
},
"details": "Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS) vulnerability in CodePeople CP Polls allows Code Injection.This issue affects CP Polls: from n/a through 1.0.71.",
"id": "GHSA-g5h8-25hr-rhch",
"modified": "2024-05-17T09:31:02Z",
"published": "2024-05-17T09:31:02Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-24874"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/vulnerability/cp-polls/wordpress-polls-cp-plugin-1-0-71-content-injection-vulnerability?_s_id=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-G956-W8R6-2M72
Vulnerability from github – Published: 2026-07-30 18:31 – Updated: 2026-07-30 18:31A carefully crafted editing request could trigger an XSS vulnerability on Apache JSPWiki when parsing errors on the markdown renderer, which could allow the attacker to execute javascript in the victim's browser and get some sensitive information about the victim.
This issue affects Apache JSPWiki: through 2.12.3.
Users are recommended to upgrade to version 2.12.4, which fixes the issue.
{
"affected": [],
"aliases": [
"CVE-2026-48910"
],
"database_specific": {
"cwe_ids": [
"CWE-80"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-07-30T16:17:12Z",
"severity": "MODERATE"
},
"details": "A carefully crafted editing request could trigger an XSS vulnerability \non Apache JSPWiki when parsing errors on the markdown renderer, which \ncould allow the attacker to execute javascript in the victim\u0027s browser \nand get some sensitive information about the victim.\n\n\nThis issue affects Apache JSPWiki: through 2.12.3.\n\nUsers are recommended to upgrade to version 2.12.4, which fixes the issue.",
"id": "GHSA-g956-w8r6-2m72",
"modified": "2026-07-30T18:31:39Z",
"published": "2026-07-30T18:31:39Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-48910"
},
{
"type": "WEB",
"url": "https://lists.apache.org/thread/yvbdjnocw5qq3xkbjs9h77ghlg0bsw2c"
},
{
"type": "WEB",
"url": "http://www.openwall.com/lists/oss-security/2026/07/30/18"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-G9VF-M9QR-PWPW
Vulnerability from github – Published: 2025-11-19 12:30 – Updated: 2025-11-19 12:30A improper neutralization of script-related html tags in a web page (basic xss) vulnerability in Fortinet FortiADC 8.0.0, FortiADC 7.6.0 through 7.6.3, FortiADC 7.4 all versions, FortiADC 7.2 all versions may allow attacker to execute unauthorized code or commands via crafted URL.
{
"affected": [],
"aliases": [
"CVE-2025-58412"
],
"database_specific": {
"cwe_ids": [
"CWE-80"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-11-19T10:15:45Z",
"severity": "MODERATE"
},
"details": "A improper neutralization of script-related html tags in a web page (basic xss) vulnerability in Fortinet FortiADC 8.0.0, FortiADC 7.6.0 through 7.6.3, FortiADC 7.4 all versions, FortiADC 7.2 all versions may allow attacker to execute unauthorized code or commands via crafted URL.",
"id": "GHSA-g9vf-m9qr-pwpw",
"modified": "2025-11-19T12:30:20Z",
"published": "2025-11-19T12:30:20Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-58412"
},
{
"type": "WEB",
"url": "https://fortiguard.fortinet.com/psirt/FG-IR-25-736"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-G9WG-98C2-QV3V
Vulnerability from github – Published: 2024-04-15 06:30 – Updated: 2025-11-03 22:35TCPDF before 6.7.4 mishandles calls that use HTML syntax.
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "tecnickcom/tcpdf"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "6.7.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-32489"
],
"database_specific": {
"cwe_ids": [
"CWE-79",
"CWE-80"
],
"github_reviewed": true,
"github_reviewed_at": "2024-04-15T18:12:08Z",
"nvd_published_at": "2024-04-15T06:15:11Z",
"severity": "MODERATE"
},
"details": "TCPDF before 6.7.4 mishandles calls that use HTML syntax.",
"id": "GHSA-g9wg-98c2-qv3v",
"modified": "2025-11-03T22:35:27Z",
"published": "2024-04-15T06:30:35Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-32489"
},
{
"type": "WEB",
"url": "https://github.com/tecnickcom/TCPDF/commit/51cd1b39de5643836e62661d162c472d63167df7"
},
{
"type": "WEB",
"url": "https://github.com/tecnickcom/TCPDF/commit/82fc97bf1c74c8dbe62b1d3cc6d10fa4b87e0262"
},
{
"type": "PACKAGE",
"url": "https://github.com/tecnickcom/TCPDF"
},
{
"type": "WEB",
"url": "https://github.com/tecnickcom/TCPDF/compare/6.6.2...6.7.4"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2025/06/msg00004.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:L/VI:L/VA:N/SC:L/SI:L/SA:N",
"type": "CVSS_V4"
}
],
"summary": "TCPDF Cross-site Scripting vulnerability"
}
GHSA-GC29-JC84-4R2V
Vulnerability from github – Published: 2025-06-27 15:31 – Updated: 2025-06-27 15:31IBM Cloud Pak System 2.3.5.0, 2.3.3.7, 2.3.3.7 iFix1 on Power and 2.3.3.6, 2.3.3.6 iFix1, 2.3.3.6 iFix2, 2.3.4.0, 2.3.4.1 on Intel operating systems is vulnerable to HTML injection. A remote attacker could inject malicious HTML code, which when viewed, would be executed in the victim's Web browser within the security context of the hosting site.
{
"affected": [],
"aliases": [
"CVE-2023-38007"
],
"database_specific": {
"cwe_ids": [
"CWE-79",
"CWE-80"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-06-27T15:15:24Z",
"severity": "MODERATE"
},
"details": "IBM Cloud Pak System 2.3.5.0, 2.3.3.7, 2.3.3.7 iFix1 on Power and 2.3.3.6, 2.3.3.6 iFix1, 2.3.3.6 iFix2, 2.3.4.0, 2.3.4.1 on Intel operating systems is vulnerable to HTML injection. A remote attacker could inject malicious HTML code, which when viewed, would be executed in the victim\u0027s Web browser within the security context of the hosting site.",
"id": "GHSA-gc29-jc84-4r2v",
"modified": "2025-06-27T15:31:29Z",
"published": "2025-06-27T15:31:29Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-38007"
},
{
"type": "WEB",
"url": "https://www.ibm.com/support/pages/node/7237162"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-GFHX-HW2G-V5HG
Vulnerability from github – Published: 2026-09-30 15:40 – Updated: 2026-09-30 15:40Impact
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": [
{
"package": {
"ecosystem": "npm",
"name": "serialize-javascript"
},
"ranges": [
{
"events": [
{
"introduced": "7.1.1"
},
{
"fixed": "7.1.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-97711"
],
"database_specific": {
"cwe_ids": [
"CWE-79",
"CWE-80"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-30T15:40:05Z",
"nvd_published_at": "2026-09-29T16:17:19Z",
"severity": "LOW"
},
"details": "### Impact\n\n`serialize-javascript` escapes its output so it is safe to embed inside a\n`\u003cscript\u003e` element. In 7.1.1 that guarantee does not hold for **function\nvalues**: a crafted function body can carry a literal, unescaped `\u003c/script\u003e`\ninto the output, terminating the script element early so the remainder is\nparsed as HTML.\n\n`SCRIPT_CLOSE_REGEXP` used `\u003c\\/script[^\u003e]*\u003e` as its first alternative. The\ncharacter class excludes only `\u003e`, so a single match could run from one\n`\u003c/script` all the way to the next `\u003e` anywhere in the source \u2014 swallowing a\nsecond, complete `\u003c/script\u003e` along the way. Only one replacement is emitted\nper match, and the plain-code branch neutralizes just the leading `\u003c`\n(`\u0027\u003c \u0027 + match.slice(1)`), so the swallowed tag was re-emitted verbatim.\n\nReaching that shape requires `\u003c/script` in code position, which is legal\nJavaScript: `x\u003c/script=+/` parses as `x \u003c /script=+/`, a comparison against a\nregex literal.\n\n```js\nconst serialize = require(\u0027serialize-javascript\u0027);\nconst src = \"function f(x){ return x\u003c/script=+/ + \u0027\u003c/script\u003e\u003cimg src=x onerror=alert(1)\u003e\u0027 }\";\nconst out = serialize({ h: new Function(\u0027return \u0027 + src)() });\n// {\"h\":function f(x){ return x\u003c /script=+/ + \u0027\u003c/script\u003e\u003cimg src=x onerror=alert(1)\u003e\u0027 }}\n```\n\nEmbedded as the README documents (`\u003cscript\u003ewindow.S = \u003c%= serialize(state) %\u003e\u003c/script\u003e`)\nand parsed by Chromium, the script element ends at the injected tag and the\n`\u003cimg\u003e` becomes a live DOM node with its `onerror` handler executing in the\npage origin.\n\nOnly the function path is affected. The same payload passed as **data** is\nescaped correctly, and `options.isJSON` / non-function values are unaffected.\n\n### Patches\n\nFixed in **7.1.2**. The wildcard now excludes `\u003c` as well as `\u003e`\n(`[^\u003c\u003e]*`), so a match can never reach past a second `\u003c`. Every `\u003c/script`\nin the source therefore either begins its own match or is followed by a\ncharacter the HTML tokenizer does not accept as ending a tag name \u2014 it ends\nthe tag name only on TAB, LF, FF, CR, SPACE, `/` or `\u003e`, and emits anything\nelse as text.\n\n### Workarounds\n\nUpgrade to **7.1.2**. If you cannot upgrade, 7.1.0 and earlier are\nunaffected, or avoid serializing functions whose source text is\nattacker-influenced.\n\n### Regression note\n\nThis is a regression specific to 7.1.1, not a long-standing issue. 7.1.0 and\nearlier applied the same wildcard but escaped the **entire** match, so no tag\nsurvived. Downstream scanners defaulting to a `\u003e= 7.1.0` range would be\noverly broad.",
"id": "GHSA-gfhx-hw2g-v5hg",
"modified": "2026-09-30T15:40:06Z",
"published": "2026-09-30T15:40:05Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/yahoo/serialize-javascript/security/advisories/GHSA-gfhx-hw2g-v5hg"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-97711"
},
{
"type": "WEB",
"url": "https://github.com/yahoo/serialize-javascript/commit/2bdbaaff9cb8a4639135eb24cfcd383d3fefb534"
},
{
"type": "PACKAGE",
"url": "https://github.com/yahoo/serialize-javascript"
},
{
"type": "WEB",
"url": "https://github.com/yahoo/serialize-javascript/releases/tag/v7.1.2"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Serialize JavaScript: Cross-site scripting (XSS) via unescaped \u003c/script\u003e in serialized function bodies"
}
Mitigation
Carefully check each input parameter against a rigorous positive specification (allowlist) defining the specific characters and format allowed. All input should be neutralized, not just parameters that the user is supposed to specify, but all data in the request, including hidden fields, cookies, headers, the URL itself, and so forth. A common mistake that leads to continuing XSS vulnerabilities is to validate only fields that are expected to be redisplayed by the site. We often encounter data from the request that is reflected by the application server or the application that the development team did not anticipate. Also, a field that is not currently reflected may be used by a future developer. Therefore, validating ALL parts of the HTTP request is recommended.
Mitigation MIT-30.1
Strategy: Output Encoding
- Use and specify an output encoding that can be handled by the downstream component that is reading the output. Common encodings include ISO-8859-1, UTF-7, and UTF-8. When an encoding is not specified, a downstream component may choose a different encoding, either by assuming a default encoding or automatically inferring which encoding is being used, which can be erroneous. When the encodings are inconsistent, the downstream component might treat some character or byte sequences as special, even if they are not special in the original encoding. Attackers might then be able to exploit this discrepancy and conduct injection attacks; they even might be able to bypass protection mechanisms that assume the original encoding is also being used by the downstream component.
- The problem of inconsistent output encodings often arises in web pages. If an encoding is not specified in an HTTP header, web browsers often guess about which encoding is being used. This can open up the browser to subtle XSS attacks.
Mitigation MIT-43
With Struts, write all data from form beans with the bean's filter attribute set to true.
Mitigation MIT-31
Strategy: Attack Surface Reduction
To help mitigate XSS attacks against the user's session cookie, set the session cookie to be HttpOnly. In browsers that support the HttpOnly feature (such as more recent versions of Internet Explorer and Firefox), this attribute can prevent the user's session cookie from being accessible to malicious client-side scripts that use document.cookie. This is not a complete solution, since HttpOnly is not supported by all browsers. More importantly, XmlHttpRequest and other powerful browser technologies provide read access to HTTP headers, including the Set-Cookie header in which the HttpOnly flag is set.
CAPEC-18: XSS Targeting Non-Script Elements
This attack is a form of Cross-Site Scripting (XSS) where malicious scripts are embedded in elements that are not expected to host scripts such as image tags (<img>), comments in XML documents (< !-CDATA->), etc. These tags may not be subject to the same input validation, output validation, and other content filtering and checking routines, so this can create an opportunity for an adversary to tunnel through the application's elements and launch a XSS attack through other elements. As with all remote attacks, it is important to differentiate the ability to launch an attack (such as probing an internal network for unpatched servers) and the ability of the remote adversary to collect and interpret the output of said attack.
CAPEC-193: PHP Remote File Inclusion
In this pattern the adversary is able to load and execute arbitrary code remotely available from the application. This is usually accomplished through an insecurely configured PHP runtime environment and an improperly sanitized "include" or "require" call, which the user can then control to point to any web-accessible file. This allows adversaries to hijack the targeted application and force it to execute their own instructions.
CAPEC-32: XSS Through HTTP Query Strings
An adversary embeds malicious script code in the parameters of an HTTP query string and convinces a victim to submit the HTTP request that contains the query string to a vulnerable web application. The web application then procedes to use the values parameters without properly validation them first and generates the HTML code that will be executed by the victim's browser.
CAPEC-86: XSS Through HTTP Headers
An adversary exploits web applications that generate web content, such as links in a HTML page, based on unvalidated or improperly validated data submitted by other actors. XSS in HTTP Headers attacks target the HTTP headers which are hidden from most users and may not be validated by web applications.