Skip to content

Add security.serverIslandBodySizeLimit and shared body-reading utility#15755

Merged
matthewp merged 5 commits intomainfrom
fix/bugbot-128
Mar 6, 2026
Merged

Add security.serverIslandBodySizeLimit and shared body-reading utility#15755
matthewp merged 5 commits intomainfrom
fix/bugbot-128

Conversation

@matthewp
Copy link
Contributor

@matthewp matthewp commented Mar 4, 2026

Changes

  • Adds a new security.serverIslandBodySizeLimit config option (defaults to 1 MB) so server islands have their own body size limit, separate from security.actionBodySizeLimit
  • Extracts the body-reading logic into a shared utility (core/request-body.ts) with readBodyWithLimit() and BodySizeLimitError, used by both Actions and Server Islands
  • The server islands POST endpoint now reads the request body incrementally with a streaming reader and rejects payloads exceeding the configured limit with a 413 response
  • Also checks the Content-Length header upfront for early rejection of oversized requests
  • Removes duplicated readRequestBodyWithLimit from the actions runtime in favor of the shared utility

Testing

  • Added unit tests for body size enforcement: oversized body returns 413, oversized Content-Length header returns 413, body within limit is accepted, default limit works when none is specified
  • All existing server islands unit tests (19 total) pass
  • All existing middleware app tests (20 total) pass
  • Actions integration tests (including "Rejects oversized JSON action body") pass

Docs

@changeset-bot
Copy link

changeset-bot bot commented Mar 4, 2026

🦋 Changeset detected

Latest commit: 4869953

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added the pkg: astro Related to the core `astro` package (scope) label Mar 4, 2026
@codspeed-hq
Copy link

codspeed-hq bot commented Mar 4, 2026

Merging this PR will improve performance by 10.28%

⚡ 1 improved benchmark
✅ 17 untouched benchmarks

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation Build: hybrid site (static + server) 8.9 s 8.1 s +10.28%

Comparing fix/bugbot-128 (4869953) with main (02e24d9)

Open in CodSpeed

…g utility

- Introduce security.serverIslandBodySizeLimit config option so server
  islands have their own body size limit separate from actions
- Extract readBodyWithLimit into a shared utility (core/request-body.ts)
  used by both actions and server islands, eliminating code duplication
- Update server islands endpoint to use the new config and shared utility
- Update actions runtime to use the shared utility while preserving
  ActionError behavior
@matthewp matthewp changed the title Harden server islands POST endpoint with body size limit Add security.serverIslandBodySizeLimit and shared body-reading utility Mar 4, 2026
matthewp added 2 commits March 4, 2026 10:56
…Length check

reader.cancel() hangs in Node.js when reading Request body streams in
the SSR build context. The original actions code never called it — just
throwing from inside the read loop is sufficient. Also restores the
upfront Content-Length check in parseRequestBody to match the original
control flow.
@matthewp matthewp marked this pull request as ready for review March 4, 2026 22:35
Copy link
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few things needs to be addressed

@@ -0,0 +1,5 @@
---
'astro': patch
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a minor, with a bigger explanation

Comment on lines +47 to +54
export class BodySizeLimitError extends Error {
limit: number;
constructor(limit: number) {
super(`Request body exceeds the configured limit of ${limit} bytes`);
this.name = 'BodySizeLimitError';
this.limit = limit;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be an Astro error. Actually, I believe we have already an error for this, probably the one we use for Astro Actions

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AstroError is for development and is an error intended for the developer, usually about something like a misconfiguration. We don't have an AstroError for this. I actually started to do what you suggest before looking at the errors and seeing that they were all for dev.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see! I think it's fine for now to keep this here, however we should have a directory for runtime errors, so they don't get scattered across the codebase

*
* @throws {BodySizeLimitError} if the body exceeds the configured limit
*/
export async function readBodyWithLimit(request: Request, limit: number): Promise<Uint8Array> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why the code of this function was changed, but with this change, we also changed the error message thrown for the actions body limit. We need to make sure we are consistent with error handling

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The actions body limit error remains the same because it gets caught and rethrown here: https://github.com/withastro/astro/pull/15755/changes#diff-81e2d08f5cbae97ab8006d21a810c86d3d6a18e3ab93d7bdc9eb5a91a03ec26cR295

@matthewp
Copy link
Contributor Author

matthewp commented Mar 5, 2026

@ematipico Updated the changeset here: 4869953

Left comments on the other two things.

Copy link
Member

@sarah11918 sarah11918 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changeset and JSDoc look great, Matthew! Thanks! 🎉

@matthewp matthewp merged commit f9ee868 into main Mar 6, 2026
27 checks passed
@matthewp matthewp deleted the fix/bugbot-128 branch March 6, 2026 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs pr pkg: astro Related to the core `astro` package (scope)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants