Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve host spoof regression test #5553

Closed
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
105 changes: 75 additions & 30 deletions test/res.location.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down Expand Up @@ -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()
});
});
})
})
})
Loading