sec-fetch-parse
v0.1.0
Published
Zero-dependency parser for HTTP Sec-Fetch-* request headers
Maintainers
Readme
sec-fetch-parse
Zero-dependency Node.js parser for HTTP Sec-Fetch- request headers.*
Implements W3C Fetch Metadata (SecFetchDest, SecFetchMode, SecFetchSite, SecFetchUser). 162 tests, TypeScript definitions, MIT licensed.
const {
parseSecFetchDest,
parseSecFetchMode,
parseSecFetchSite,
parseSecFetchUser,
InvalidSecFetchHeader,
} = require('sec-fetch-parse');
const dest = parseSecFetchDest('image'); // → 'image'
const mode = parseSecFetchMode('cors'); // → 'cors'
const site = parseSecFetchSite('same-origin'); // → 'same-origin'
const user = parseSecFetchUser('?1'); // → trueWhy?
The fetch-metadata npm package enforces Fetch Metadata policy by rejecting non-conforming requests, but it does not expose a typed parser for individual Sec-Fetch-* header values. Every server that wants to log, inspect, or conditionally route based on fetch metadata must hand-roll string splitting. No zero-dependency npm package parses these four headers into typed objects — until now.
sec-fetch-parse fills that gap with a small, focused, zero-dependency parser that follows the W3C Fetch Metadata spec exactly.
Quick start
npm install sec-fetch-parseconst {
parseSecFetchDest,
parseSecFetchMode,
parseSecFetchSite,
parseSecFetchUser,
InvalidSecFetchHeader,
} = require('sec-fetch-parse');
// Basic parsing — every W3C enum value parses back to itself.
parseSecFetchDest('document'); // → 'document'
parseSecFetchMode('navigate'); // → 'navigate'
parseSecFetchSite('cross-site'); // → 'cross-site'
parseSecFetchUser('?1'); // → true (the only valid true value)
// Sec-Fetch-User: ?1 → true; absent/null/undefined/empty → false.
parseSecFetchUser(undefined); // → false (absent header)
parseSecFetchUser(''); // → false
parseSecFetchUser('?0'); // → false (?1 is the only valid true)
// Unknown / future values passthrough for forward-compatibility (per W3C spec).
parseSecFetchDest('custom-value'); // → 'custom-value'
// Invalid types throw InvalidSecFetchHeader.
try {
parseSecFetchDest(42);
} catch (err) {
if (err instanceof InvalidSecFetchHeader) {
// handle
}
}Real-world middleware example
const express = require('express');
const {
parseSecFetchDest,
parseSecFetchMode,
parseSecFetchSite,
parseSecFetchUser,
} = require('sec-fetch-parse');
const app = express();
app.use((req, res, next) => {
const dest = parseSecFetchDest(req.headers['sec-fetch-dest']);
const mode = parseSecFetchMode(req.headers['sec-fetch-mode']);
const site = parseSecFetchSite(req.headers['sec-fetch-site']);
const isUser = parseSecFetchUser(req.headers['sec-fetch-user']);
// OWASP CSRF defense: cross-origin iframe embeds of our pages are forbidden.
if (dest === 'iframe' && site === 'cross-site') {
return res.status(403).send('Embedding not allowed');
}
// Log structured fetch metadata for audit trails.
console.log({ dest, mode, site, isUser });
next();
});API
parseSecFetchDest(value: unknown): string
Parse a Sec-Fetch-Dest header value.
- Returns the value as-is (passthrough semantics per W3C forward-compatibility clause).
- Throws
InvalidSecFetchHeaderifvalueis not a string.
W3C enum (16 known values): audio, audiowave, video, image, font, script, style, track, embed, object, document, serviceworker, sharedworker, worker, manifest, xslt.
parseSecFetchMode(value: unknown): string
Parse a Sec-Fetch-Mode header value.
- Returns the value as-is (passthrough).
- Throws
InvalidSecFetchHeaderifvalueis not a string.
W3C enum (7 known values): navigate, same-origin, no-site (deprecated), no-cors, cors, websocket, preflight.
parseSecFetchSite(value: unknown): string
Parse a Sec-Fetch-Site header value.
- Returns the value as-is (passthrough).
- Throws
InvalidSecFetchHeaderifvalueis not a string.
W3C enum (4 known values): cross-site, same-origin, same-site, none.
parseSecFetchUser(value: unknown): boolean
Parse a Sec-Fetch-User header value.
- Returns
trueonly for?1(the only valid value per W3C spec). - Returns
falseforundefined,null, or empty string (absent header semantics). - Throws
InvalidSecFetchHeaderfor any other type.
InvalidSecFetchHeader
Error class thrown when input type is invalid. Extends Error; err.name === 'InvalidSecFetchHeader'. Use instanceof to distinguish from generic Errors.
TypeScript
index.d.ts is included. No need for @types/sec-fetch-parse.
import {
parseSecFetchDest,
parseSecFetchMode,
parseSecFetchSite,
parseSecFetchUser,
InvalidSecFetchHeader,
} from 'sec-fetch-parse';
const dest: string = parseSecFetchDest('document');
const isUser: boolean = parseSecFetchUser('?1');tsc --noEmit index.d.ts passes cleanly.
Testing
npm testRuns the full test suite via node --test tests/*.test.js. 162 tests across 5 test files, all passing. Each of the 35 spec acceptance criteria has at least one dedicated test.
Out of scope (limitations / non-goals)
- No policy enforcement. If you need a middleware that rejects non-conforming requests, use
fetch-metadata. This library only parses. Sec-Fetch-Digestis NOT supported — it is a response header (digest integrity), not a request header. Separate concern.- No browser-side header construction. This is a server-side parser.
- No network I/O. This library is pure logic, no HTTP client/server.
- No header normalization. Whitespace and case are significant; the parser does not trim. W3C defines values as lowercase ASCII; non-conforming values passthrough verbatim.
Evidence of need
sec-fetch-parsename is available on npm — verified 2026-08-05,npm view sec-fetch-parsereturns 404.fetch-metadata(jperasmus, MIT) enforces policy but does not parse. Multiple GitHub issues request parsed access; the maintainer's stated position is that the package is "middleware for enforcing Fetch metadata request header checking," not a parser.- W3C Fetch Metadata spec defines precise grammar for all four headers; this library follows it.
- OWASP lists Fetch Metadata request header checking as a Tier 1 server-side CSRF defense.
References
- W3C Fetch Metadata: https://w3c.github.io/webappsec-fetch-metadata/
- MDN: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Dest
- OWASP CSRF Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html
License
MIT — see LICENSE.
