diff --git a/test/res.location.js b/test/res.location.js index 38cab027a8..afb89e8226 100644 --- a/test/res.location.js +++ b/test/res.location.js @@ -45,36 +45,6 @@ describe('res', function(){ .expect(200, done) }) - it('should not encode bad "url"', function (done) { - var app = express() - - app.use(function (req, res) { - // This is here to show a basic check one might do which - // would pass but then the location header would still be bad - if (url.parse(req.query.q).host !== 'google.com') { - res.status(400).end('Bad url'); - } - res.location(req.query.q).end(); - }); - - request(app) - .get('/?q=http://google.com\\@apple.com') - .expect(200) - .expect('Location', 'http://google.com\\@apple.com') - .end(function (err) { - if (err) { - throw err; - } - - // This ensures that our protocol check is case insensitive - request(app) - .get('/?q=HTTP://google.com\\@apple.com') - .expect(200) - .expect('Location', 'HTTP://google.com\\@apple.com') - .end(done) - }); - }); - it('should not touch already-encoded sequences in "url"', function (done) { var app = express() @@ -145,5 +115,80 @@ describe('res', function(){ .expect(200, done) }) }) + + describe("Host Spoofing attack", function() { + + it('parsed host should not change after Location is set', function (done) { + var app = express() + var inputUrl; + + app.use(function (req, res) { + // This is here to show a basic check one might do which + // would pass but then the location header would still be bad + if (url.parse(req.query.q).host !== 'google.com') { + res.status(400).end('Bad url'); + } + inputUrl = req.query.q + res.location(req.query.q).end(); + }); + + request(app) + .get('/?q=http://google.com\\@apple.com') + .expect(200) + .expect('Location', 'http://google.com\\@apple.com') + + .end(function (err, res) { + if (err) { + throw err; + } + // Parse the hosts from the input URL and the Location header + var inputHost = url.parse(inputUrl).host; + var locationHost = url.parse(res.headers['location']).host; + + // Assert that the hosts are the same + if (inputHost !== locationHost) { + return done(new Error('Hosts do not match: ' + inputHost + " !== " + locationHost)); + } + + done() + }); + }); + + it('parsed host should not change after Location is set, even when protocol is uppercase', function (done) { + var app = express() + var inputUrl; + + app.use(function (req, res) { + // This is here to show a basic check one might do which + // would pass but then the location header would still be bad + if (url.parse(req.query.q).host !== 'google.com') { + res.status(400).end('Bad url'); + } + inputUrl = req.query.q + res.location(req.query.q).end(); + }); + + request(app) + .get('/?q=HTTP://google.com\\@apple.com') + .expect(200) + .expect('Location', 'HTTP://google.com\\@apple.com') + + .end(function (err, res) { + if (err) { + throw err; + } + // Parse the hosts from the input URL and the Location header + var inputHost = url.parse(inputUrl).host; + var locationHost = url.parse(res.headers['location']).host; + + // Assert that the hosts are the same + if (inputHost !== locationHost) { + return done(new Error('Hosts do not match: ' + inputHost + " !== " + locationHost)); + } + + done() + }); + }); + }) }) })