first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
# `crit` enforcement
## Purpose
RFC 7515 §4.1.11 enforcement: every entry in `header.crit` MUST be in the caller's `acceptableCriticalHeaders` allowlist. The RFC's intent is that callers refuse to verify any token whose protected header carries critical parameters they do not understand — otherwise the producer could downgrade security guarantees (e.g. an `exp` claim becoming critical against a verifier that ignores it). This module owns that gate.
## Features
- Empty `crit` array rejected.
- Non-array `crit` rejected.
- Non-string entry rejected.
- `crit` referencing itself rejected (RFC 7515 §4.1.11 MUST).
- Entry not in caller's allowlist → `JWS.CRIT_UNRECOGNIZED`.
- Entry in allowlist accepted.
## Usage: Basic Example
```ts
import { enforceCrit, parseHeader } from "@suaveplan/jws";
const header = parseHeader("eyJhbGciOiJIUzI1NiIsImNyaXQiOlsiZXhwIl0sImV4cCI6MTYwfQ");
enforceCrit(header, ["exp"]); // does not throw
```
## Usage: Advanced Example
```ts
import { enforceCrit, JwsError } from "@suaveplan/jws";
try {
enforceCrit({ alg: "HS256", crit: ["exp", "tenant"] }, ["exp"]);
} catch (err) {
if (err instanceof JwsError && err.code === "JWS.CRIT_UNRECOGNIZED") {
// Reject the token: a critical parameter is outside the allowlist.
}
}
// Self-reference rejected:
try {
enforceCrit({ alg: "HS256", crit: ["crit"] }, ["crit"]);
} catch (err) {
if (err instanceof JwsError && err.code === "JWS.CRIT_MALFORMED") {
// RFC 7515 §4.1.11 MUST.
}
}
```
## API Reference
- `enforceCrit(header: JoseHeader, acceptableCriticalHeaders: readonly string[] | undefined): void`
- No-op when `header.crit` is absent.
- Throws `JwsError(JWS.CRIT_MALFORMED)` for shape failures (non-array, empty, non-string entry, self-reference).
- Throws `JwsError(JWS.CRIT_UNRECOGNIZED)` for entries not on the allowlist.
## Implementation Notes
The allowlist is supplied at every verify call rather than configured globally; this is deliberate because the allowlist is fundamentally a property of the consumer's threat model, not the JWS library. Callers integrating an RFC 7797 `b64: false` token MUST add `"b64"` to their `acceptableCriticalHeaders` even though this package implements the RFC 7797 spec internally — the gate is "do you know what to do with this parameter," not "does the library implement it." This makes it impossible to accidentally accept a `b64: false` token through a verifier that wasn't expecting one.