fix(audit-2026-06-11/H-1): request-body ceilings (Caddy proxy + email-inbound webhook)
- Caddy request_body { max_size 12MB } in both Caddyfiles — a hard
ceiling replacing Caddy's multi-GB default; 12MB clears the
orchestrator's 10 MiB user-route read. Validated with caddy validate.
- email-inbound router gets an explicit DefaultBodyLimit::max(1MB):
the public unauthenticated webhook previously rode Axum's 2MB
extractor default; tightened so a flood can't force large
allocation + JSON parse per request.
Admin / execute handlers keep Axum's 2MB extractor default (already
bounded); the user-route path keeps its explicit 10 MiB manual read.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,15 @@
|
||||
}
|
||||
|
||||
:80 {
|
||||
# Audit 2026-06-11 (H-1) — hard request-body ceiling at the proxy.
|
||||
# Without this, Caddy forwards bodies up to its multi-GB default to
|
||||
# picloud. 12 MB sits just above the orchestrator's 10 MiB user-route
|
||||
# read so legitimate large invokes pass; admin / email handlers are
|
||||
# bounded far tighter by their own Axum extractor limits.
|
||||
request_body {
|
||||
max_size 12MB
|
||||
}
|
||||
|
||||
# Baseline headers applied to every response.
|
||||
header {
|
||||
X-Content-Type-Options "nosniff"
|
||||
|
||||
@@ -19,6 +19,15 @@
|
||||
{$PICLOUD_DOMAIN} {
|
||||
encode zstd gzip
|
||||
|
||||
# Audit 2026-06-11 (H-1) — hard request-body ceiling at the proxy.
|
||||
# Without this, Caddy forwards bodies up to its multi-GB default to
|
||||
# picloud. 12 MB sits just above the orchestrator's 10 MiB user-route
|
||||
# read so legitimate large invokes pass; admin / email handlers are
|
||||
# bounded far tighter by their own Axum extractor limits.
|
||||
request_body {
|
||||
max_size 12MB
|
||||
}
|
||||
|
||||
# Baseline headers on every response. HSTS is unconditional in prod.
|
||||
header {
|
||||
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
||||
|
||||
@@ -169,12 +169,20 @@ pub struct EmailInboundState {
|
||||
pub bad_sig_limiter: Arc<BadSignatureLimiter>,
|
||||
}
|
||||
|
||||
/// Per-request body cap for the inbound webhook. Inbound email events
|
||||
/// are small JSON envelopes (from/to/subject/body); 1 MiB is generous.
|
||||
/// Audit 2026-06-11 (H-1) — this public, unauthenticated endpoint
|
||||
/// otherwise rode Axum's 2 MB extractor default; pin it explicitly and
|
||||
/// tighter so a flood can't force large allocations + JSON parses.
|
||||
const INBOUND_BODY_LIMIT_BYTES: usize = 1024 * 1024;
|
||||
|
||||
pub fn email_inbound_router(state: EmailInboundState) -> Router {
|
||||
Router::new()
|
||||
.route(
|
||||
"/email-inbound/{app_id}/{trigger_id}",
|
||||
post(receive_inbound_email),
|
||||
)
|
||||
.layer(axum::extract::DefaultBodyLimit::max(INBOUND_BODY_LIMIT_BYTES))
|
||||
.with_state(state)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user