Skip to content

Commit

Permalink
[security] Sanitize paths, hosts before parsing.
Browse files Browse the repository at this point in the history
  • Loading branch information
3rd-Eden committed Jul 29, 2018
1 parent f60fa4e commit 53b1794
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 9 deletions.
30 changes: 21 additions & 9 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ var required = require('requires-port')
var rules = [
['#', 'hash'], // Extract from the back.
['?', 'query'], // Extract from the back.
function sanitize(address) { // Sanitize what is left of the address
return address.replace('\\', '/');
},
['/', 'pathname'], // Extract from the back.
['@', 'auth', 1], // Extract from the front.
[NaN, 'host', undefined, 1, 1], // Set left over value.
Expand Down Expand Up @@ -47,7 +50,7 @@ var ignore = { hash: 1, query: 1 };
*
* @param {Object|String} loc Optional default location object.
* @returns {Object} lolcation object.
* @api public
* @public
*/
function lolcation(loc) {
var location = global && global.location || {};
Expand Down Expand Up @@ -89,7 +92,7 @@ function lolcation(loc) {
*
* @param {String} address URL we want to extract from.
* @return {ProtocolExtract} Extracted information.
* @api private
* @private
*/
function extractProtocol(address) {
var match = protocolre.exec(address);
Expand All @@ -107,7 +110,7 @@ function extractProtocol(address) {
* @param {String} relative Pathname of the relative URL.
* @param {String} base Pathname of the base URL.
* @return {String} Resolved pathname.
* @api private
* @private
*/
function resolve(relative, base) {
var path = (base || '/').split('/').slice(0, -1).concat(relative.split('/'))
Expand Down Expand Up @@ -140,11 +143,14 @@ function resolve(relative, base) {
* create an actual constructor as it's much more memory efficient and
* faster and it pleases my OCD.
*
* It is worth noting that we should not use `URL` as class name to prevent
* clashes with the global URL instance that got introduced in browsers.
*
* @constructor
* @param {String} address URL we want to parse.
* @param {Object|String} location Location defaults for relative paths.
* @param {Boolean|Function} parser Parser for the query string.
* @api public
* @private
*/
function Url(address, location, parser) {
if (!(this instanceof Url)) {
Expand Down Expand Up @@ -190,10 +196,16 @@ function Url(address, location, parser) {
// When the authority component is absent the URL starts with a path
// component.
//
if (!extracted.slashes) instructions[2] = [/(.*)/, 'pathname'];
if (!extracted.slashes) instructions[3] = [/(.*)/, 'pathname'];

for (; i < instructions.length; i++) {
instruction = instructions[i];

if (typeof instruction === 'function') {
address = instruction(address);
continue;
}

parse = instruction[0];
key = instruction[1];

Expand Down Expand Up @@ -284,8 +296,8 @@ function Url(address, location, parser) {
* used to parse the query.
* When setting the protocol, double slash will be
* removed from the final url if it is true.
* @returns {URL}
* @api public
* @returns {URL} URL instance for chaining.
* @public
*/
function set(part, value, fn) {
var url = this;
Expand Down Expand Up @@ -370,8 +382,8 @@ function set(part, value, fn) {
* Transform the properties back in to a valid and full URL string.
*
* @param {Function} stringify Optional query stringify function.
* @returns {String}
* @api public
* @returns {String} Compiled version of the URL.
* @public
*/
function toString(stringify) {
if (!stringify || 'function' !== typeof stringify) stringify = qs.stringify;
Expand Down
29 changes: 29 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,28 @@ describe('url-parse', function () {
assume(parsed.pathname).equals('/b/c');
});

it('ignores \\ in pathnames', function () {
var url = 'http://google.com:80\\@yahoo.com/#what\\is going on'
, parsed = parse(url);

assume(parsed.port).equals('');
assume(parsed.username).equals('');
assume(parsed.password).equals('');
assume(parsed.hostname).equals('google.com');
assume(parsed.hash).equals('#what\\is going on');

parsed = parse('//\\what-is-up.com');
assume(parsed.pathname).equals('/what-is-up.com');
});

it('correctly ignores multiple slashes //', function () {
var url = '////what-is-up.com'
, parsed = parse(url);

assume(parsed.host).equals('');
assume(parsed.hostname).equals('');
});

describe('origin', function () {
it('generates an origin property', function () {
var url = 'http://google.com:80/pathname'
Expand Down Expand Up @@ -252,6 +274,13 @@ describe('url-parse', function () {
o = parse('wss://google.com:80/pathname');
assume(o.origin).equals('wss://google.com:80');
});

it('maintains the port number for non-default port numbers', function () {
var parsed = parse('http://google.com:8080/pathname');

assume(parsed.host).equals('http://google.com:8080');
assume(parsed.href).equals('http://google.com:8080/pathname');
});
});

describe('protocol', function () {
Expand Down

0 comments on commit 53b1794

Please sign in to comment.