first commit
This commit is contained in:
57
docs/security-stack/security/jws/src/header/crit.md
Normal file
57
docs/security-stack/security/jws/src/header/crit.md
Normal 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.
|
||||
Reference in New Issue
Block a user