BaseHttpClient forwards Authorization across a cross-origin redirect
Author: janbucharCreated Sep 16, 2026Updated Sep 16, 2026
Labelst-tooling
buildRedirectRequest()copies every header of the previous request onto the next one, with no origin check- the Fetch standard drops
Authorizationwhen a redirect changes origin, and nativefetchdoes; the manual redirect loop does not, so a token sent to one host is handed to whatever host it redirects to - relevant wherever
sendRequestcarries credentials and the redirect target isn't trusted - same method as #4133
import { createServer } from 'node:http';
import { FetchHttpClient } from '@crawlee/http-client';
const victim = createServer((req, res) => {
console.log('second host saw:', req.headers.authorization ?? '(none)');
res.writeHead(200).end('ok');
});
await new Promise((resolve) => victim.listen(0, resolve));
const redirector = createServer((_req, res) => {
res.writeHead(302, { location: `http://127.0.0.1:${victim.address().port}/end` });
res.end();
});
await new Promise((resolve) => redirector.listen(0, resolve));
const url = `http://127.0.0.1:${redirector.address().port}/start`;
await new FetchHttpClient().sendRequest(new Request(url, { headers: { authorization: 'Bearer secret' } }));
// second host saw: Bearer secret
await fetch(url, { headers: { authorization: 'Bearer secret' } });
// second host saw: (none)@crawlee/[email protected], Node 26.8.2.
Source: apify/crawlee