Skip to content

Commit

Permalink
Reject invalid redirects
Browse files Browse the repository at this point in the history
Fixes #234.
  • Loading branch information
Rob--W committed May 6, 2020
1 parent 0a3b8e9 commit a9e06a9
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 2 deletions.
7 changes: 5 additions & 2 deletions lib/cors-anywhere.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,12 @@ function onProxyResponse(proxy, proxyReq, proxyRes, req, res) {
// Handle redirects
if (statusCode === 301 || statusCode === 302 || statusCode === 303 || statusCode === 307 || statusCode === 308) {
var locationHeader = proxyRes.headers.location;
var parsedLocation;
if (locationHeader) {
locationHeader = url.resolve(requestState.location.href, locationHeader);

parsedLocation = parseURL(locationHeader);
}
if (parsedLocation) {
if (statusCode === 301 || statusCode === 302 || statusCode === 303) {
// Exclude 307 & 308, because they are rare, and require preserving the method + request body
requestState.redirectCount_ = requestState.redirectCount_ + 1 || 1;
Expand All @@ -186,7 +189,7 @@ function onProxyResponse(proxy, proxyReq, proxyRes, req, res) {
req.method = 'GET';
req.headers['content-length'] = '0';
delete req.headers['content-type'];
requestState.location = parseURL(locationHeader);
requestState.location = parsedLocation;

// Remove all listeners (=reset events to initial state)
req.removeAllListeners();
Expand Down
5 changes: 5 additions & 0 deletions test/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ nock('http://example.com')
.get('/redirectwithoutlocation')
.reply(302, 'maybe found')

.get('/redirectinvalidlocation')
.reply(302, 'redirecting to junk...', {
Location: 'http:///',
})

.get('/proxyerror')
.replyWithError('throw node')
;
Expand Down
13 changes: 13 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,19 @@ describe('Basic functionality', function() {
.expect(302, 'maybe found', done);
});

it('GET with 302 redirect to an invalid Location should not be followed', function(done) {
// There is nothing to follow, so let the browser decide what to do with it.
request(cors_anywhere)
.get('/example.com/redirectinvalidlocation')
.redirects(0)
.expect('Access-Control-Allow-Origin', '*')
.expect('x-request-url', 'http://example.com/redirectinvalidlocation')
.expect('x-final-url', 'http://example.com/redirectinvalidlocation')
.expect('access-control-expose-headers', /x-final-url/)
.expect('Location', 'http:///')
.expect(302, 'redirecting to junk...', done);
});

it('POST with 307 redirect should not be handled', function(done) {
// Because of implementation difficulties (having to keep the request body
// in memory), handling HTTP 307/308 redirects is deferred to the requestor.
Expand Down

0 comments on commit a9e06a9

Please sign in to comment.