Harden HTTP defaults and proxy header trust.

Add explicit server timeout/header limits, require trusted proxy CIDRs when honoring forwarded IP headers, and document single-instance storage expectations.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-31 21:09:00 -05:00
parent dbf112a5b7
commit dbb72da312
7 changed files with 246 additions and 27 deletions
+26
View File
@@ -28,6 +28,21 @@ All configuration is YAML.
- `listen_addr`: address for the HTTP server (required).
- Default: `:8080`
- `read_header_timeout`: maximum time for reading request headers.
- Must be `> 0`
- Default: `5s`
- `read_timeout`: maximum time for reading the full request.
- Must be `> 0`
- Default: `30s`
- `write_timeout`: maximum time allowed for writing the response.
- Must be `> 0`
- Default: `30s`
- `idle_timeout`: maximum keep-alive idle time between requests.
- Must be `> 0`
- Default: `120s`
- `max_header_bytes`: max HTTP header size in bytes.
- Must be `> 0`
- Default: `1048576` (1 MiB)
### `limits`
@@ -64,7 +79,11 @@ All configuration is YAML.
- Add trusted IPs/CIDRs for LAN/proxy clients (for example `192.168.1.0/24`)
- Empty list means no allowlist restriction
- `trust_proxy_headers`: if `true`, client IP extraction honors `X-Forwarded-For` then `X-Real-IP`.
- Only used when source IP matches `trusted_proxy_ips`.
- Keep `false` unless behind a trusted reverse proxy that sets these headers.
- `trusted_proxy_ips`: list of reverse-proxy IPs/CIDRs permitted to supply forwarded headers.
- Required when `trust_proxy_headers: true`
- Examples: `127.0.0.1`, `10.0.0.0/8`
- `rate_limit.enabled`: enable per-IP token-bucket rate limiting on write route.
- Default: `true`
- `rate_limit.requests_per_minute`: steady refill rate per client IP.
@@ -103,3 +122,10 @@ If exposed beyond a trusted LAN, place a reverse proxy in front (Nginx, Caddy, T
- Monitoring and log retention suitable for abuse triage.
Recommended baseline: run behind a reverse proxy, keep low TTL and size limits, and use `allowed_ips` for write access whenever possible.
## Storage Model
Scratchbox storage is designed for a single process instance per `storage.data_dir`.
- Do not run multiple scratchbox processes against the same data directory.
- Metadata/index writes are process-local and are not coordinated with cross-process locking.