feat(helmet): HTTP response security headers#49
Merged
Merged
Conversation
Adds a new framework-agnostic security headers package matching helmet 8.x
parity (14 options + 7 aliases) plus modern standards: Permissions-Policy,
Reporting-Endpoints, NEL, Integrity-Policy, Clear-Site-Data, COEP,
Document-Policy/Isolation-Policy, Trusted Types, per-request nonce
injection, and batched validation that aggregates every violation into a
single throw.
Static helpers (Helmet.csp / hsts / permissionsPolicy / referrerPolicy /
xFrameOptions / xContentTypeOptions / originAgentCluster / crossOrigin{Opener,
Resource,Embedder}Policy) provide tree-shake-friendly equivalents of helmet's
sub-middleware. Companion tooling: 11 environment presets (strict, api, spa,
observatoryAPlus, amp, oauth, kisa, acsc, bsi, ncsc, ipa), helmet.js v8/v9
fromHelmetOptions migration, csp-evaluator-equivalent lintCsp, parseCspReport
(legacy + Reporting API normalisation with strict body/Content-Type/timeout
hardening), hashFromString (Web Crypto SRI), Csp keyword constants, and
RFC 9651 structured-fields serialisation.
Companion: extends @zipbul/shared HttpHeader enum with 30+ security header
names. PLAN.md updated with @zipbul/result usage policy, deep-freeze
semantics, derive() re-validation contract, parseCspReport input validation,
xPoweredBy/removeHeaders conflict resolution, and Permissions-Policy
registry reconcile table.
Tests: 136 pass / 0 fail / 256 expect calls across 13 files. Covers full
helmet 8.x option matrix (defaults, false to disable, every value variant),
nonce fallback safety (regression for default-src preservation), apply()
semantics (304 skip, set-if-absent vs always-overwrite, multi Set-Cookie,
Response.redirect), prototype-pollution guards, batched validation
aggregation, CSP cross-reference of report-to with reportingEndpoints.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the legacy agent guidance files from the repository. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ader Strip framework adapters, presets, non-HTTP serializers, and helmet@npm migration shim — these belong in separate packages, not in a runtime- agnostic security headers engine. - Remove src/adapters/ (next/sveltekit/remix/astro/hono/elysia/electron) - Remove src/serializers/ (meta-tag/tauri/extension-manifest) - Remove src/presets.ts and src/migration.ts - Remove safe-regex2 dep (input length cap + bounded regex already guard ReDoS) - Collapse 17 subpath exports to a single `.` entry — every subpath funneled through Helmet.create() so tree-shake benefit was zero, only overhead SRP — one HTTP header per directory: - Split src/simple-headers/ → 10 dirs (referrer-policy, x-frame-options, x-content-type-options, x-dns-prefetch-control, x-permitted-cross- domain-policies, x-xss-protection, x-download-options, origin-agent- cluster, timing-allow-origin, x-robots-tag) - Split src/cross-origin/ → coop/, coep/, corp/ - Promote shared HeaderEntry type to src/header-entry.ts Bug fix: - CSP nonce strip leaves no orphan ' ;' between directives (helmet.ts) Tests + docs: - Add test/golden.test.ts (Default-ON snapshot lock + nonce invariants) - Add test/new-surface.test.ts (Helmet.endpoints + nonce edge cases + Response 304/opaque + Set-Cookie passthrough + CSP fuzz) - Add test/helmet.bench.test.ts (microbench for hot paths) - Rewrite README.md and README.ko.md to scope-accurate quickstart - Drop helmet-parity test (express-helmet compat is out of scope) 122 pass / 0 fail
Standards-driven fixes verified directly against W3C/IETF/WHATWG sources: - sf-string rejects non-ASCII (RFC 9651 §3.3.3) - sf-decimal enforces 12-digit integer cap (RFC 9651 §3.3.2) - frame-ancestors restricted to scheme/host/'self'/'none' — rejects nonces, hashes, and all keywords other than 'self'/'none' (CSP3 §6.4.2) - Referrer-Policy rejects empty token list (W3C §4.1: 1#policy-token) - X-Permitted-Cross-Domain-Policies adds 'by-ftp-filename' - Timing-Allow-Origin restricted to origin form, no path/fragment (Resource Timing §3.5.2) - Reporting endpoint URL strips fragment (W3C Reporting-1 §3.6) - Permissions-Policy: drop 'publickey-credentials-create' (not in W3C registry); add 22 missing registry features (ch-ua-*, document-domain, window-placement, focus-without-user-activation, conversion-measurement, join-ad-interest-group, manual-text, monetization, run-ad-auction, sync-script, trust-token-redemption, vertical-scroll). Tier names mirror registry sections (Standardized / Proposed / Experimental / Retired). ch-ua-* deliberately excluded from default-deny set. - COEP / COOP support `report-to="<endpoint>"` parameter, cross-validated against reportingEndpoints (HTML §7.1.3.1 / §7.1.4.1) - X-Robots-Tag directive grammar validation (Google Search Central spec): boolean rules, max-snippet/max-image-preview/max-video-preview/ unavailable_after value forms, optional bot-name prefix, CRLF guard - document-policy: prototype-chain check for Object.create() attacks - Removed dead nonce control-char branch in csp/source-validate (NONCE_RE alphabet excludes control chars by construction) Coverage: line 79.5% → 100.00%, function ~80% → 99.74% Tests: 124 → 315 (1005 expect calls), 0 fail Adds property-based fuzz tests for sf-string round-trip, decimal range, malformed CSP source rejection, and CR/LF absence in emitted headers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# Conflicts: # bun.lock # packages/shared/src/enums/http-header.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Helmet middleware package — HTTP response security headers engine.