From 7a8596e6fb6d9aed6268145ebe43005d9e6ca94d Mon Sep 17 00:00:00 2001 From: Jacob Ebey Date: Mon, 18 Mar 2024 11:01:08 -0700 Subject: [PATCH] fix: do not follow redirect if scheme is not an HTTP(S) scheme (#62) --- .changeset/healthy-buckets-drum.md | 5 +++++ packages/fetch/src/fetch.js | 8 ++++++++ packages/fetch/test/main.js | 9 +++++++++ packages/fetch/test/utils/server.js | 6 ++++++ 4 files changed, 28 insertions(+) create mode 100644 .changeset/healthy-buckets-drum.md diff --git a/.changeset/healthy-buckets-drum.md b/.changeset/healthy-buckets-drum.md new file mode 100644 index 0000000..786c5fd --- /dev/null +++ b/.changeset/healthy-buckets-drum.md @@ -0,0 +1,5 @@ +--- +"@remix-run/web-fetch": patch +--- + +If locationURL’s scheme is not an HTTP(S) scheme, then return a network error. https://fetch.spec.whatwg.org/#http-redirect-fetch diff --git a/packages/fetch/src/fetch.js b/packages/fetch/src/fetch.js index 6a76542..8ced217 100644 --- a/packages/fetch/src/fetch.js +++ b/packages/fetch/src/fetch.js @@ -180,6 +180,14 @@ async function fetch(url, options_ = {}) { return; } + // https://fetch.spec.whatwg.org/#http-redirect-fetch + // 6. If locationURL’s scheme is not an HTTP(S) scheme, then return a network error. + if (locationURL.protocol !== 'http:' && locationURL.protocol !== 'https:') { + reject(new FetchError('URL scheme must be a HTTP(S) scheme', 'bad-redirect-scheme')); + finalize(); + return; + } + // HTTP-redirect fetch step 6 (counter increment) // Create a new Request object. const requestOptions = { diff --git a/packages/fetch/test/main.js b/packages/fetch/test/main.js index 9388bce..610faff 100644 --- a/packages/fetch/test/main.js +++ b/packages/fetch/test/main.js @@ -461,6 +461,15 @@ describe("node-fetch", () => { }); }); + it("should not follow non HTTP(s) redirect", () => { + const url = `${base}redirect/301/file`; + const options = { + }; + return expect(fetch(url, options)) + .to.eventually.be.rejected.and.be.an.instanceOf(FetchError) + .and.have.property("type", "bad-redirect-scheme"); + }); + it("should allow not following redirect", () => { const url = `${base}redirect/301`; const options = { diff --git a/packages/fetch/test/utils/server.js b/packages/fetch/test/utils/server.js index 2c28ab8..eaa3925 100644 --- a/packages/fetch/test/utils/server.js +++ b/packages/fetch/test/utils/server.js @@ -235,6 +235,12 @@ export default class TestServer { res.end(); } + if (p === '/redirect/301/file') { + res.statusCode = 301; + res.setHeader('Location', 'file://inspect'); + res.end(); + } + if (p === '/redirect/301/rn') { res.statusCode = 301 res.setHeader('Location', '/403')