Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: expressjs/express
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 4.19.1
Choose a base ref
...
head repository: expressjs/express
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4.19.2
Choose a head ref
  • 2 commits
  • 4 files changed
  • 3 contributors

Commits on Mar 25, 2024

  1. Improved fix for open redirect allow list bypass

    Co-authored-by: Jon Church <me@jonchurch.com>
    Co-authored-by: Blake Embrey <hello@blakeembrey.com>
    3 people committed Mar 25, 2024
    Copy the full SHA
    da4d763 View commit details
  2. 4.19.2

    wesleytodd committed Mar 25, 2024
    Copy the full SHA
    04bc627 View commit details
Showing with 281 additions and 64 deletions.
  1. +5 −0 History.md
  2. +11 −20 lib/response.js
  3. +1 −1 package.json
  4. +264 −43 test/res.location.js
5 changes: 5 additions & 0 deletions History.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
4.19.2 / 2024-03-25
==========

* Improved fix for open redirect allow list bypass

4.19.1 / 2024-03-20
==========

31 changes: 11 additions & 20 deletions lib/response.js
Original file line number Diff line number Diff line change
@@ -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;

// 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));

// set location
return this.set('Location', encodedUrl);
return this.set('Location', loc);
};

/**
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "express",
"description": "Fast, unopinionated, minimalist web framework",
"version": "4.19.1",
"version": "4.19.2",
"author": "TJ Holowaychuk <tj@vision-media.ca>",
"contributors": [
"Aaron Heckmann <aaron.heckmann+github@gmail.com>",
Loading