Registry / web-framework / fetch-metadata

fetch-metadata

JSON →
library1.0.0jsnpmunverified

The `fetch-metadata` package provides Node.js middleware designed for Express and Connect applications to enforce browser Fetch metadata request headers, such as `Sec-Fetch-Site`, `Sec-Fetch-Mode`, and `Sec-Fetch-Dest`. This middleware plays a crucial role in enhancing application security by helping to prevent common web vulnerabilities like Cross-Site Request Forgery (CSRF), Cross-Site Script Inclusion (XSSI), and information leakage attacks, as part of a defense-in-depth strategy. Currently at stable version 1.0.0, it offers a highly configurable API allowing developers to define granular policies for request origins, navigation types, and specific allowed paths. While a specific release cadence isn't published, its initial stable release suggests a focus on reliability for security-critical applications. Its key differentiator lies in its specific focus on these modern browser security headers, providing a ready-to-use solution for integrating these protections into existing Node.js web servers.

npm install fetch-metadata
INSTALL
IMPORT
SIG · FETCH-METADATA
F
fetch-metadata
web-frameworkjavascriptv1.0.0
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

fetchMetadata
import fetchMetadata from 'fetch-metadata'
const fetchMetadata = require('fetch-metadata')
This library primarily uses a default export, typically consumed as a function to initialize the middleware. While it ships TypeScript types, the import pattern remains the same for both JavaScript and TypeScript.
FetchMetadataOptions
import type { FetchMetadataOptions } from 'fetch-metadata'
For TypeScript users, the configuration options type can be imported for stronger type checking when defining middleware options.

Demonstrates how to install `fetch-metadata` and integrate it into an Express application with a basic configuration. This example shows how to set allowed fetch sites, disallow specific navigation requests, define allowed paths to bypass checks, and implement a custom error handler.

import express from 'express'; import fetchMetadata from 'fetch-metadata'; const app = express(); const port = 3000; // Apply the fetch-metadata middleware with custom configuration. // It will allow 'same-origin', 'same-site', and 'none' (user interaction) requests. // It will block navigation requests trying to embed 'object' or 'embed' elements. app.use( fetchMetadata({ allowedFetchSites: ['same-origin', 'same-site', 'none'], disallowedNavigationRequests: ['object', 'embed'], errorStatusCode: 403, allowedPaths: [ '/public-data', // Allow access to this path regardless of fetch metadata { path: '/health-check', method: 'GET' } // Allow GET requests to /health-check ], onError: (request, response, next, options) => { console.warn(`[Fetch Metadata] Blocked request to ${request.url} from site ${request.headers['sec-fetch-site'] || 'N/A'}`); response.status(options.errorStatusCode).send('Access Denied: Request blocked by security policy.'); // For testing or specific bypasses, you could call next() here to allow the request: // next(); } }) ); // Define a simple root route app.get('/', (req, res) => { res.send(` <h1>Fetch Metadata Middleware Demo</h1> <p>This server enforces Fetch Metadata Request Headers.</p> <p>Try making requests from different origins or contexts using browser dev tools.</p> <p>A fetch from 'same-origin' to /protected should succeed.</p> <a href="/public-data">Public Data (always allowed)</a><br/> <a href="/health-check">Health Check (GET allowed)</a> <script> fetch('/protected') .then(response => response.text()) .then(text => console.log('GET /protected (same-origin):', text)) .catch(error => console.error('GET /protected (same-origin) failed:', error)); fetch('/public-data') .then(response => response.text()) .then(text => console.log('GET /public-data (allowed path):', text)) .catch(error => console.error('GET /public-data (allowed path) failed:', error)); </script> `); }); // A protected route that relies on fetch metadata policies app.get('/protected', (req, res) => { res.send('You accessed a protected resource (Sec-Fetch-Site: same-origin/same-site/none allowed).'); }); // An explicitly allowed public route via 'allowedPaths' app.get('/public-data', (req, res) => { res.send('This is public data, accessible via allowedPaths config.'); }); // A health check route with a specific method allowed via 'allowedPaths' app.get('/health-check', (req, res) => { res.status(200).send('Service is healthy!'); }); // Start the server app.listen(port, () => { console.log(`Server listening on http://localhost:${port}`); console.log('To test: Open in browser, then try to fetch /protected from a different origin (e.g., using browser console or a separate HTML page on another domain).'); });
Debug
Known issues
gotchaMisconfiguring `allowedFetchSites` or `disallowedNavigationRequests` can unintentionally block legitimate requests, leading to application downtime or degraded user experience. Understand the implications of each `Sec-Fetch-*` header value before deployment.
fix
Thoroughly test configurations in various browser contexts and user scenarios. Start with a more permissive configuration and tighten it gradually, monitoring logs for blocked requests (e.g., via the `onError` callback).
affects: >=1.0.0
gotchaWhen providing a custom `onError` callback, it is crucial to ensure that the function either terminates the response (e.g., `response.end()`, `response.send()`) or explicitly calls `next()` to pass control to the next middleware. Failing to do so will cause the request to hang indefinitely.
fix
Always ensure your `onError` implementation includes `response.status(statusCode).send(message)` or `next()`.
affects: >=1.0.0
gotchaThe `allowedPaths` configuration uses the `url-pattern` library for path matching, which might have subtle differences compared to Express's native path-to-regexp parsing. While it supports dynamic segments, be mindful of exact syntax for complex patterns.
fix
Refer to the `url-pattern` documentation for advanced path matching syntax. Test all `allowedPaths` entries thoroughly, especially those with dynamic segments or regular expressions, to ensure they match as expected.
affects: >=1.0.0
Errors
Common errors & fixes
TypeError: fetchMetadata is not a function
Attempting to use `require('fetch-metadata')` without accessing the default export, or using `import { fetchMetadata } from 'fetch-metadata'` instead of a default import.
fix
Use `import fetchMetadata from 'fetch-metadata'` for ESM modules, or `const fetchMetadata = require('fetch-metadata').default` for CommonJS environments (though the former is recommended).
Access Denied: Request blocked by security policy.
A request was blocked by the middleware's policy, likely due to an unexpected `Sec-Fetch-Site` or `Sec-Fetch-Dest` header value, or a request to a non-allowed path.
fix
Check the server console for warnings from the `onError` callback. Adjust `allowedFetchSites`, `disallowedNavigationRequests`, or add the problematic path to `allowedPaths` configuration. Ensure your client-side requests are sending appropriate Fetch Metadata headers.
Request hangs indefinitely (no response from server).
The custom `onError` callback was implemented without sending a response or passing control to the next middleware, leaving the request unresolved.
fix
Modify your `onError` callback to either call `response.status(statusCode).send(message)` to terminate the request with an error, or `next()` if you wish to bypass the block and allow the request to proceed (e.g., for logging and allowing in specific cases).
Upgrade
Version history
1.0.0latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
32 hits · last 30 days
node
28
OpenAI (training)
1
Resources
fetch-metadata — npm install fetch-metadata · libregistry