mirror of
https://github.com/expressjs/express.git
synced 2026-02-22 03:51:36 +00:00
Improved fix for open redirect allow list bypass
Co-authored-by: Jon Church <me@jonchurch.com> Co-authored-by: Blake Embrey <hello@blakeembrey.com>
This commit is contained in:
@@ -34,7 +34,6 @@ var extname = path.extname;
|
||||
var mime = send.mime;
|
||||
var resolve = path.resolve;
|
||||
var vary = require('vary');
|
||||
var urlParse = require('url').parse;
|
||||
|
||||
/**
|
||||
* Response prototype.
|
||||
@@ -56,6 +55,7 @@ module.exports = res
|
||||
*/
|
||||
|
||||
var charsetRegExp = /;\s*charset\s*=/;
|
||||
var schemaAndHostRegExp = /^(?:[a-zA-Z][a-zA-Z0-9+.-]*:)?\/\/[^\\\/\?]+/;
|
||||
|
||||
/**
|
||||
* Set status `code`.
|
||||
@@ -905,32 +905,23 @@ res.cookie = function (name, value, options) {
|
||||
*/
|
||||
|
||||
res.location = function location(url) {
|
||||
var loc = String(url);
|
||||
var loc;
|
||||
|
||||
// "back" is an alias for the referrer
|
||||
if (url === 'back') {
|
||||
loc = this.req.get('Referrer') || '/';
|
||||
} else {
|
||||
loc = String(url);
|
||||
}
|
||||
|
||||
var lowerLoc = loc.toLowerCase();
|
||||
var encodedUrl = encodeUrl(loc);
|
||||
if (lowerLoc.indexOf('https://') === 0 || lowerLoc.indexOf('http://') === 0) {
|
||||
try {
|
||||
var parsedUrl = urlParse(loc);
|
||||
var parsedEncodedUrl = urlParse(encodedUrl);
|
||||
// Because this can encode the host, check that we did not change the host
|
||||
if (parsedUrl.host !== parsedEncodedUrl.host) {
|
||||
// If the host changes after encodeUrl, return the original url
|
||||
return this.set('Location', loc);
|
||||
}
|
||||
} catch (e) {
|
||||
// If parse fails, return the original url
|
||||
return this.set('Location', loc);
|
||||
}
|
||||
}
|
||||
var m = schemaAndHostRegExp.exec(loc);
|
||||
var pos = m ? m[0].length + 1 : 0;
|
||||
|
||||
// set location
|
||||
return this.set('Location', encodedUrl);
|
||||
// Only encode after host to avoid invalid encoding which can introduce
|
||||
// vulnerabilities (e.g. `\\` to `%5C`).
|
||||
loc = loc.slice(0, pos) + encodeUrl(loc.slice(pos));
|
||||
|
||||
return this.set('Location', loc);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user