Skip to content

Security: notchrisbutler/http

Security

docs/security.md

Security and Abuse Model

Documentation home · Architecture · Challenge fixtures · Operations

Trust boundary

Every request, header, cookie, URL component, query parameter, and body is attacker-controlled. Every route is designed as if it were already exposed publicly.

The service intentionally returns synthetic diagnostics and fixture data. It does not fetch arbitrary upstream URLs, proxy traffic, collect real credentials, retain request content, or reproduce third-party anti-bot implementations.

Primary threats

Threat Required control
Compute, bandwidth, or connection exhaustion Hard limits, streaming, route-class rate policies, bounded timing, no blocking loops
SSRF and proxy abuse No arbitrary upstream fetching; future work requires an explicit allowlist and separate security review
Open redirects Same-origin paths or explicit host allowlists with validation at every redirect
Header injection and response splitting Parsed values, explicit header allowlist, value-length and character validation
Cache poisoning Denied hop-by-hop and platform-sensitive headers; deliberate cache keys and Vary behavior
Credential or cookie disclosure Default redaction, synthetic-only echo mode, no sensitive logging
XSS through reflected fixture input Context-appropriate escaping and restrictive fixture-specific CSP
Token forgery, expiry, and replay Web Crypto signatures, short lifetimes, scopes, timing-safe checks, and state only where replay prevention requires it
Cross-request data leakage No request-scoped mutable module state
Privacy-invasive telemetry Structured aggregate fields only; no bodies, credentials, full IP addresses, or fingerprints

Baseline limits

Central hard ceilings are defined in src/config/constants.ts. Individual fixtures may impose smaller limits. Tests cover immediately below, at, and above important boundaries.

Shared ceilings include a 1 MiB inspected request body, 256 KiB generated or range body, 10 redirects, 10 seconds of delay, 100 stream items, 8 KiB query and normalized header values—including the combined Cookie header—64 normalized headers, and 10 minutes for any session. Cookie inspection considers at most the first 50 segments and truncates inspected values to 4 KiB; it does not claim per-cookie rejection. Response-producing routes enforce and document their own output bounds rather than relying on a single global response-size gate. Implemented challenge sessions are narrower at 120 seconds. Long-lived routes use a dedicated low rate class; Workers isolate concurrent invocations, and no route creates application-global queues or blocking loops.

Logs

Completion logs contain a request ID, optional fixture identifier, route template, method, status, duration, response-size bucket, rate-limit decision, and error code. They must not contain raw headers, queries, bodies, cookies, authorization values, IP addresses, or fingerprints.

Secrets

Production secrets are owner-managed Wrangler secrets. Local development uses ignored .dev.vars values. Secret names may be documented; values must never be committed, logged, echoed, placed in commands, or included in public health, version, error, or OpenAPI responses.

Challenge tokens are HMAC-SHA-256 signed, versioned, bounded to five minutes, scope checked, canonically encoded, and compared in constant time. New tokens use CHALLENGE_SIGNING_KEY. During rotation, an optional CHALLENGE_SIGNING_KEY_PREVIOUS verifies existing tokens while the current key issues all new state. Keep the previous key only for the maximum five-minute structural lifetime, then remove it. Production fails closed if the current key is missing or shorter than 32 characters.

Completed abuse-case review

Abuse case Review result and evidence
Arbitrary proxy or SSRF No route accepts an upstream URL or performs caller-directed Fetch. Repository search and OpenAPI review cover the public surface.
Open redirect Redirect inputs are parsed as same-origin paths or exact allowlisted hosts; schemes, credentials, depth, and external origins are tested. Challenge redirects are fixed literals.
Resource exhaustion All generated bytes, body reads, redirects, delays, streams, retries, queries, headers, cookies, and challenge lifetimes are bounded and assigned a rate class. Wire/timing/boundary tests exercise the meaningful ceilings.
Credential collection or disclosure Authorization and cookies redact by default; only explicit test_/synthetic_ values may echo. Captured log tests prove secrets, query values, and IPs are absent.
XSS or script injection Reflected HTML values are escaped, response headers are allowlisted, and browser/challenge pages use restrictive CSPs. No route accepts templates or executable source.
Cache poisoning Diagnostic and challenge state uses no-store; cache fixtures allow only documented keys and validators; unsafe response headers are denied.
Token forgery, cross-scope use, replay HMAC, canonical encoding, exact scope, expiry, and timing-safe comparison are unit tested. Strict sequence replay uses a per-session Durable Object with expiry cleanup.
CAPTCHA or anti-bot misuse All challenges are branded synthetic simulations. The mock CAPTCHA has a fixed documented answer, no vendor integration, and no solving or bypass behavior.
Privacy-invasive state or telemetry Logs contain only aggregate operational fields. The sole stored row contains a random nonce-derived object identity, numeric stage, and expiry, then an alarm deletes it.
Supply-chain/runtime dependency exposure Production browser pages load only repository assets; the former third-party documentation UI was removed. Lockfiles and exact Python contract pins make local/CI resolution reproducible.

No reviewed abuse case requires an undocumented production exception. Edge WAF, custom-domain TLS, distributed counters, and retention settings remain owner-configured platform controls and are called out in deployment/operations guides rather than claimed as locally proven.

Deferred capabilities

If a requested fixture cannot be made safe, bounded, standards-correct, and inspectable on Workers, it is deferred with evidence and a reproducible verification plan rather than implemented with weakened controls.

There aren't any published security advisories