I've created a very basic service worker, that logs the request headers on fetch
event:
self.addEventListener('fetch', event => {
console.log("- Fetch -");
for (const pair of event.request.headers.entries()) {
console.log(pair[0]+ ': '+ pair[1]);
}
});
On the main page, I'm fetching the same page like so:
function fetchPage() {
fetch(location.href);
}
When logging the headers I'm getting just the following 2 headers:
- Fetch -
service-worker.js:12 accept: */*
service-worker.js:12 user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36
Why can't I see any other/custom headers?
Is it a security limitation?
Yes, these headers are intentionally hidden. The general behaviour of header list and request objects is specified in the Fetch standard.
The non-normative section "HTTP header layer division" in that specification explains that requests proceed in three stages, all of which may modify the header list, while client code relying on the Fetch and Service Worker specifications only has access to the first two. So your service worker receives the list of headers at the moment before those other headers are even added.
The Fetch specification also includes a list of forbidden header names that client code can never set under any circumstances; these headers are entirely controlled by the user agent. There are also other mechanisms that limit client code access to header lists, like those related to CORS.
The reason for all this is indeed security: this guarantees that certain headers cannot be read or tampered with by malicious script code attempting to perform request forgery (crafting a malicious header that the server may rely on coming from a trusted source), browser fingerprinting (identifying the user by HTTP headers) or secret extraction (e.g. exfiltrating cookies from request headers).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With