testing/cross_backend/credential_header_robustness.ts

Cross-backend credential-header robustness probe — the auth sibling of body_size_smuggling.ts.

The auth middleware reads a single credential per header (Authorization, X-Daemon-Token). What a *duplicated*, *oversized*, or *control-char-injected* credential header does is framework-territory — Hono reads its headers via the Web Headers API, axum via http::HeaderMap — and the two could resolve a duplicate differently (first-vs-last), cap header size differently, or parse a malformed value differently. None of that is exercised over fetch (the FetchTransport can't emit a duplicate or malformed header), so it had no cross-impl pin. This raw-socket suite sends hand-framed requests and asserts the security invariants that must hold regardless of how each framework resolves the ambiguity — so it pins a real property without blessing one resolution over the other:

  • a duplicated credential header never escalates — a request carrying a valid keeper X-Daemon-Token *and* a second, conflicting one must not perform a keeper operation. The target omits confirm, so the documented confirm guard (purge_not_confirmed) makes the honored-token branch a guaranteed non-2xx with zero side effect, and the discarded-token branch is a non-2xx auth/credential refusal — so whichever copy the framework picks, the outcome is non-2xx. The same shape with two garbage Authorization headers pins the bearer path can't be escalated either.
  • a control-char-injected credential header can't smuggle or authenticate — embedded CRLF / bare CR in the value never frames a second request (no smuggle) and never authenticates (the truncated / rejected value is no token).
  • no response desync — each crafted request yields exactly one HTTP response (a duplicate header that reframed the request would surface as a second status line, like the body-size smuggling probe).
  • an oversized credential header can't wedge the server — after a request with a 64 KiB X-Daemon-Token (well past both frameworks' header caps), a subsequent normal request on a fresh connection still gets a response. The oversized request's own outcome (4xx / 431 / connection close) is don't-care; surviving it is the property.

Raw-socket by necessity (fetch can't emit duplicate or malformed headers), so — like body_size_smuggling.ts — this is cross-process only and fixture-free: it needs only the base URL, the RPC path, and a valid daemon token (handle.daemon_token, kept current for the run by the same rotation the _testing_reset channel relies on). Cited property: docs/security.md §"Credential Type Hierarchy" (a leaked / conflicting credential header can't escalate the credential ceiling) + §"API Token Security" (bearer handling).

$lib-free by contract (relative + node: specifiers only).

view source

Declarations
#

2 declarations

CredentialHeaderRobustnessCrossTestOptions
#

testing/cross_backend/credential_header_robustness.ts view source

CredentialHeaderRobustnessCrossTestOptions import type {CredentialHeaderRobustnessCrossTestOptions} from '@fuzdev/fuz_app/testing/cross_backend/credential_header_robustness.js';

Options for the credential-header robustness probe — needs the raw URL + a valid daemon token.

base_url

Base URL the spawned backend is reachable at (e.g. http://localhost:1178).

type string

readonly

rpc_path?

RPC endpoint path to target. Default /api/rpc.

type string

readonly

daemon_token

A valid daemon token (keeper) — handle.daemon_token.

type string

readonly

describe_credential_header_robustness_cross_tests
#

Depends on
#