Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions lib/redirect.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,27 @@ Redirect.prototype.onResponse = function (response) {

self.redirects.push({ statusCode: response.statusCode, redirectUri: redirectTo })

// if the redirect hostname (not just port or protocol) is changed:
// if the redirect origin (protocol, hostname or port) is changed:
// 1. remove host header, the new host will be populated on request.init
// 2. remove authorization header, avoid authentication leak
// 2. remove cookie header, avoid session leak across origins
// 3. remove authorization header, avoid authentication leak
// @note: This is done because of security reasons, irrespective of the
// status code or request method used.
if (request.headers && uriPrev.hostname !== request.uri.hostname) {
// @note: comparing full origin (protocol + hostname + port) so that
// credentials are not leaked across ports or on a protocol downgrade
// (e.g. https -> http), not just when the hostname changes.
var prevOrigin = uriPrev.protocol + '//' + uriPrev.hostname + (uriPrev.port ? ':' + uriPrev.port : '')
var nextOrigin = request.uri.protocol + '//' + request.uri.hostname + (request.uri.port ? ':' + request.uri.port : '')
if (request.headers && prevOrigin !== nextOrigin) {
request.removeHeader('host')

// remove cookie header, avoid session cookie leak across origins
request.removeHeader('cookie')

// clear the cached original cookie header so it isn't re-prepended
// to the Cookie header on subsequent hops (see Request.prototype.jar)
delete request.originalCookieHeader

// use followAuthorizationHeader option to retain authorization header
if (!self.followAuthorizationHeader) {
request.removeHeader('authorization')
Expand Down
Loading