Skip to content
This repository has been archived by the owner on Dec 16, 2024. It is now read-only.

Commit

Permalink
Add allowInsecureRedirect option
Browse files Browse the repository at this point in the history
Cherry-pick c5bcf21

Co-authored-by: Szymon Drosdzol <[email protected]>
  • Loading branch information
2 people authored and kevinvanrijn committed Sep 24, 2024
1 parent d0a8bcc commit 45d9254
Show file tree
Hide file tree
Showing 12 changed files with 32 additions and 4 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,7 @@ The first argument can be either a `url` or an `options` object. The only requir
- `followAuthorizationHeader` - retain `authorization` header when a redirect happens to a different hostname (default: `false`)
- `maxRedirects` - the maximum number of redirects to follow (default: `10`)
- `removeRefererHeader` - removes the referer header when a redirect happens (default: `false`). **Note:** if true, referer header set in the initial request is preserved during redirect chain.
- `allowInsecureRedirect` - allows cross-protocol redirects (HTTP to HTTPS and vice versa). **Warning:** may lead to bypassing anti SSRF filters (default: `false`)

---

Expand Down
6 changes: 5 additions & 1 deletion lib/redirect.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ function Redirect (request) {
this.redirects = []
this.redirectsFollowed = 0
this.removeRefererHeader = false
this.allowInsecureRedirect = false
}

Redirect.prototype.onRequest = function (options) {
Expand Down Expand Up @@ -44,6 +45,9 @@ Redirect.prototype.onRequest = function (options) {
if (options.followAuthorizationHeader !== undefined) {
self.followAuthorizationHeader = options.followAuthorizationHeader
}
if (options.allowInsecureRedirect !== undefined) {
self.allowInsecureRedirect = options.allowInsecureRedirect
}
}

Redirect.prototype.redirectTo = function (response) {
Expand Down Expand Up @@ -122,7 +126,7 @@ Redirect.prototype.onResponse = function (response, callback) {
request.uri = urlParser.parse(redirectTo)

// handle the case where we change protocol from https to http or vice versa
if (request.uri.protocol !== uriPrev.protocol) {
if (request.uri.protocol !== uriPrev.protocol && self.allowInsecureRedirect) {
delete request.agent
}

Expand Down
2 changes: 1 addition & 1 deletion tests/test-httpModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ function runTests (name, httpModules) {
tape(name, function (t) {
var toHttps = 'http://localhost:' + plainServer.port + '/to_https'
var toPlain = 'https://localhost:' + httpsServer.port + '/to_plain'
var options = { httpModules: httpModules, strictSSL: false }
var options = { httpModules: httpModules, strictSSL: false, allowInsecureRedirect: true }
var modulesTest = httpModules || {}

clearFauxRequests()
Expand Down
1 change: 1 addition & 0 deletions tests/test-redirect-auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ request = request.defaults({
user: 'test',
pass: 'testing'
},
allowInsecureRedirect: true,
rejectUnauthorized: false
})

Expand Down
1 change: 1 addition & 0 deletions tests/test-redirect-complex.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ tape('lots of redirects', function (t) {
request({
url: (i % 2 ? s.url : ss.url) + '/a',
headers: { 'x-test-key': key },
allowInsecureRedirect: true,
rejectUnauthorized: false
}, function (err, res, body) {
t.equal(err, null)
Expand Down
4 changes: 2 additions & 2 deletions tests/test-redirect-multi-version.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ tape('setup', function (t) {
})

tape('HTTP to HTTP2', function (t) {
var options = { strictSSL: false, protocolVersion: 'auto' }
var options = { strictSSL: false, protocolVersion: 'auto', allowInsecureRedirect: true }
request('http://localhost:' + plainServer.port + '/redir/http2', options, function (err, res, body) {
t.equal(err, null)
t.equal(body, 'http2')
Expand All @@ -97,7 +97,7 @@ tape('HTTPS to HTTP2', function (t) {
})

tape('HTTP2 to HTTP', function (t) {
var options = { strictSSL: false, protocolVersion: 'auto' }
var options = { strictSSL: false, protocolVersion: 'auto', allowInsecureRedirect: true }
request('https://localhost:' + http2Server.port + '/redir', options, function (err, res, body) {
t.equal(err, null)
t.equal(body, 'plain')
Expand Down
13 changes: 13 additions & 0 deletions tests/test-redirect.js
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,7 @@ tape('http to https redirect', function (t) {
hits = {}
request.get({
uri: require('url').parse(s.url + '/ssl'),
allowInsecureRedirect: true,
rejectUnauthorized: false
}, function (err, res, body) {
t.equal(err, null)
Expand All @@ -542,6 +543,18 @@ tape('http to https redirect', function (t) {
})
})

tape('http to https redirect should fail without the explicit "allowInsecureRedirect" option', function (t) {
hits = {}
request.get({
uri: require('url').parse(s.url + '/ssl'),
rejectUnauthorized: false
}, function (err, res, body) {
t.notEqual(err, null)
t.equal(err.message, 'Protocol "https:" not supported. Expected "http:"', 'Failed to cross-protocol redirect')
t.end()
})
})

tape('should have referer header by default when following redirect', function (t) {
request.post({
uri: s.url + '/temp',
Expand Down
1 change: 1 addition & 0 deletions tests/test-tunnel-response.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ function addTests () {

runTest('https->http over http, tunnel=default, with proxy response', {
url: ss.url + '/redirect/http',
allowInsecureRedirect: true,
proxy: s.url
}, [
'http connect to localhost:' + ss.port,
Expand Down
1 change: 1 addition & 0 deletions tests/test-tunnel.js
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ function addTests () {

runTest('https->http over http, tunnel=default', {
url: ss.url + '/redirect/http',
allowInsecureRedirect: true,
proxy: s.url
}, [
'http connect to localhost:' + ss.port,
Expand Down
2 changes: 2 additions & 0 deletions tests/test-verbose-auto-http2.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ tape('HTTP: verbose=true', function (t) {
tape('HTTP: redirect(HTTPS) + verbose=true', function (t) {
var options = {
verbose: true,
allowInsecureRedirect: true,
strictSSL: false,
protocolVersion: 'auto'
}
Expand Down Expand Up @@ -153,6 +154,7 @@ tape('HTTPS: verbose=true', function (t) {
tape('HTTPS: redirect(HTTP) + verbose=true', function (t) {
var options = {
verbose: true,
allowInsecureRedirect: true,
strictSSL: false,
protocolVersion: 'auto'
}
Expand Down
2 changes: 2 additions & 0 deletions tests/test-verbose-http2.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ tape('HTTP: verbose=true', function (t) {
tape('HTTP: redirect(HTTPS) + verbose=true', function (t) {
var options = {
verbose: true,
allowInsecureRedirect: true,
strictSSL: false,
protocolVersion: 'http2'
}
Expand Down Expand Up @@ -191,6 +192,7 @@ tape('HTTPS Gzip: verbose=true', function (t) {
tape('HTTPS: redirect(HTTP) + verbose=true', function (t) {
var options = {
verbose: true,
allowInsecureRedirect: true,
strictSSL: false,
protocolVersion: 'http2'
}
Expand Down
2 changes: 2 additions & 0 deletions tests/test-verbose.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ tape('HTTP: verbose=true', function (t) {
tape('HTTP: redirect(HTTPS) + verbose=true', function (t) {
var options = {
verbose: true,
allowInsecureRedirect: true,
strictSSL: false
}

Expand Down Expand Up @@ -189,6 +190,7 @@ tape('HTTPS Gzip: verbose=true', function (t) {
tape('HTTPS: redirect(HTTP) + verbose=true', function (t) {
var options = {
verbose: true,
allowInsecureRedirect: true,
strictSSL: false
}

Expand Down

0 comments on commit 45d9254

Please sign in to comment.