From fddad0e7ea3fd6da01cc006fdf0ed304ccdd7990 Mon Sep 17 00:00:00 2001 From: victal Date: Tue, 19 Jul 2022 17:38:01 -0300 Subject: [PATCH] fix(headers): don't forward secure headers on protocol change (#1605) backport for #1599 to the 2.x branch Co-authored-by: Guilherme Victal --- src/index.js | 16 +++++++++++++++- test/test.js | 23 +++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 1a25e800d..f39ed3a93 100644 --- a/src/index.js +++ b/src/index.js @@ -36,6 +36,20 @@ const isDomainOrSubdomain = (destination, original) => { ); }; +/** + * isSameProtocol reports whether the two provided URLs use the same protocol. + * + * Both domains must already be in canonical form. + * @param {string|URL} original + * @param {string|URL} destination + */ +const isSameProtocol = (destination, original) => { + const orig = new URL(original).protocol; + const dest = new URL(destination).protocol; + + return orig === dest; +}; + /** * Fetch function @@ -214,7 +228,7 @@ export default function fetch(url, opts) { size: request.size }; - if (!isDomainOrSubdomain(request.url, locationURL)) { + if (!isDomainOrSubdomain(request.url, locationURL) || !isSameProtocol(request.url, locationURL)) { for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { requestOpts.headers.delete(name); } diff --git a/test/test.js b/test/test.js index 36fe7703e..21cf24055 100644 --- a/test/test.js +++ b/test/test.js @@ -1677,6 +1677,29 @@ describe('node-fetch', () => { }); }); + it('should not forward secure headers to changed protocol', async () => { + const res = await fetch('https://httpbin.org/redirect-to?url=http%3A%2F%2Fhttpbin.org%2Fget&status_code=302', { + headers: new Headers({ + cookie: 'gets=removed', + cookie2: 'gets=removed', + authorization: 'gets=removed', + 'www-authenticate': 'gets=removed', + 'other-safe-headers': 'stays', + 'x-foo': 'bar' + }) + }); + + const headers = new Headers((await res.json()).headers); + // Safe headers are not removed + expect(headers.get('other-safe-headers')).to.equal('stays'); + expect(headers.get('x-foo')).to.equal('bar'); + // Unsafe headers should not have been sent to downgraded http + expect(headers.get('cookie')).to.equal(null); + expect(headers.get('cookie2')).to.equal(null); + expect(headers.get('www-authenticate')).to.equal(null); + expect(headers.get('authorization')).to.equal(null); + }); + it('should forward secure headers to same host', () => { return fetch(`${base}redirect-to/302/${base}inspect`, { headers: new Headers({