diff --git a/lib/fetch/index.js b/lib/fetch/index.js index c89c9b7ffcb..5323c30abc8 100644 --- a/lib/fetch/index.js +++ b/lib/fetch/index.js @@ -1200,6 +1200,10 @@ async function httpRedirectFetch (fetchParams, response) { if (!sameOrigin(requestCurrentURL(request), locationURL)) { // https://fetch.spec.whatwg.org/#cors-non-wildcard-request-header-name request.headersList.delete('authorization') + + // "Cookie" and "Host" are forbidden request-headers, which undici doesn't implement. + request.headersList.delete('cookie') + request.headersList.delete('host') } // 14. If request’s body is non-null, then set request’s body to the first return diff --git a/test/fetch/redirect-cross-origin-header.js b/test/fetch/redirect-cross-origin-header.js new file mode 100644 index 00000000000..fca48c44ea0 --- /dev/null +++ b/test/fetch/redirect-cross-origin-header.js @@ -0,0 +1,48 @@ +'use strict' + +const { test } = require('tap') +const { createServer } = require('http') +const { once } = require('events') +const { fetch } = require('../..') + +test('Cross-origin redirects clear forbidden headers', async (t) => { + t.plan(5) + + const server1 = createServer((req, res) => { + t.equal(req.headers.cookie, undefined) + t.equal(req.headers.authorization, undefined) + + res.end('redirected') + }).listen(0) + + const server2 = createServer((req, res) => { + t.equal(req.headers.authorization, 'test') + t.equal(req.headers.cookie, 'ddd=dddd') + + res.writeHead(302, { + ...req.headers, + Location: `http://localhost:${server1.address().port}` + }) + res.end() + }).listen(0) + + t.teardown(() => { + server1.close() + server2.close() + }) + + await Promise.all([ + once(server1, 'listening'), + once(server2, 'listening') + ]) + + const res = await fetch(`http://localhost:${server2.address().port}`, { + headers: { + Authorization: 'test', + Cookie: 'ddd=dddd' + } + }) + + const text = await res.text() + t.equal(text, 'redirected') +})