Skip to content

fix(proxy): fail closed on unsafe Apps Script uploads#1365

Open
maybeknott wants to merge 1 commit into
therealaleph:mainfrom
maybeknott:fix/apps-script-payload-ceiling
Open

fix(proxy): fail closed on unsafe Apps Script uploads#1365
maybeknott wants to merge 1 commit into
therealaleph:mainfrom
maybeknott:fix/apps-script-payload-ceiling

Conversation

@maybeknott
Copy link
Copy Markdown

@maybeknott maybeknott commented May 23, 2026

Apps Script materializes request bodies before user script code can stream or validate them. In apps_script mode, forwarding an oversized or unbounded mutating request risks relay failure after the browser has already started uploading bytes.

This change adds a local fail-closed upload guard for Apps Script relay paths. Mutating requests (POST, PUT, PATCH) are rejected with HTTP 413 Payload Too Large before the local proxy reads the request body when any of these conditions apply:

  • Content-Length is greater than 5 MiB
  • Transfer-Encoding includes chunked
  • the mutating request has no declared Content-Length

Small mutating requests still pass through normally, and non-mutating requests are ignored by the guard. The check is applied on both the MITM HTTPS relay path and the plain HTTP proxy path while preserving non-Apps-Script modes.

The guide documents the local 413 behavior in English and Persian so users understand that this is an Apps Script boundary guard, not a destination-server error.

Validation:

  • git diff --check upstream/main..HEAD
  • cargo test apps_script_upload_guard --lib
  • cargo test mitm_large_upload_returns_413_before_reading_body --lib

Apps Script receives relay requests as fully materialized HTTP bodies before script code can inspect, stream, or reject them. A mutating upload with an oversized body, chunked transfer encoding, or no declared Content-Length cannot be bounded reliably once it has entered the Apps Script execution path. The local proxy now enforces that boundary before reading or forwarding the body.

The Apps Script proxy path now defines a conservative 5 MiB request-body ceiling for mutating methods. POST, PUT, and PATCH requests are rejected when Content-Length exceeds that ceiling, when Transfer-Encoding includes chunked, or when Content-Length is absent. Non-mutating requests are ignored by this policy, and malformed Content-Length parsing remains delegated to the existing body parser so unrelated request-validation behavior is unchanged.

The HTTPS MITM relay path applies the guard immediately after parsing the request head and before read_body can buffer application bytes. The plain HTTP relay path receives the current runtime mode and applies the same guard only in apps_script mode. Rejected requests receive a local HTTP/1.1 413 Payload Too Large response with Connection: close and a short body explaining the Apps Script 5 MiB limit.

The user guide now documents the visible 413 behavior in both English and Persian so operators understand that this is a client-side safety boundary for Apps Script mode rather than an upstream server failure.

Focused proxy tests cover allowed small mutating requests, ignored non-mutating requests, oversized Content-Length rejection, chunked mutating upload rejection, missing-length mutating upload rejection, and the HTTPS MITM path returning 413 before body bytes are required.
@github-actions github-actions Bot added the type: fix fix: PR — auto-applied by release-drafter label May 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: fix fix: PR — auto-applied by release-drafter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant