diff --git a/index.js b/index.js index ecb05f7..02f37ea 100644 --- a/index.js +++ b/index.js @@ -392,8 +392,9 @@ RedirectableRequest.prototype._processResponse = function (response) { var redirectUrlParts = url.parse(redirectUrl); Object.assign(this._options, redirectUrlParts); - // Drop the confidential headers when redirecting to another domain - if (!(redirectUrlParts.host === currentHost || isSubdomainOf(redirectUrlParts.host, currentHost))) { + // Drop confidential headers when redirecting to another scheme:domain + if (redirectUrlParts.protocol !== currentUrlParts.protocol || + !isSameOrSubdomain(redirectUrlParts.host, currentHost)) { removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers); } @@ -559,7 +560,10 @@ function abortRequest(request) { request.abort(); } -function isSubdomainOf(subdomain, domain) { +function isSameOrSubdomain(subdomain, domain) { + if (subdomain === domain) { + return true; + } const dot = subdomain.length - domain.length - 1; return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain); } diff --git a/test/test.js b/test/test.js index 9e8e45f..7d2f122 100644 --- a/test/test.js +++ b/test/test.js @@ -1522,6 +1522,36 @@ describe("follow-redirects", function () { }); }); }); + + it("drops the header when redirected to a different scheme", function () { + app.get("/a", redirectsTo(302, "http://localhost:3601/b")); + app.get("/b", function (req, res) { + res.end(JSON.stringify(req.headers)); + }); + + var opts = url.parse("https://localhost:3601/a"); + opts.ca = ca; + opts.headers = {}; + opts.headers[header] = "the header value"; + + // Intercept the scheme + opts.beforeRedirect = function (options) { + assert.equal(options.protocol, "http:"); + options.protocol = "https:"; + }; + + return server.start(httpsOptions(app)) + .then(asPromise(function (resolve, reject) { + https.get(opts, resolve).on("error", reject); + })) + .then(asPromise(function (resolve, reject, res) { + res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); + })) + .then(function (str) { + var body = JSON.parse(str); + assert.equal(body[header.toLowerCase()], undefined); + }); + }); }); describe("when the followRedirects option is set to false", function () {