Skip to content
This repository has been archived by the owner on Jul 15, 2019. It is now read-only.

Commit

Permalink
first draft of URL whitelist filter
Browse files Browse the repository at this point in the history
  • Loading branch information
adon committed Oct 2, 2015
1 parent 849449b commit 2767614
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions src/xss-filters.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,57 @@ exports._getPrivFilters = function () {
}
return null;
}

/*
* Create URL whitelist filter
* Ref: https://url.spec.whatwg.org/#url-parsing
* @param {boolean} allowAllSafeURIs - to enable inherited protocol (//), blob:, http://, https://, ftp://, "data:image/[gif,jpeg,png];base64," are allowed
* @param {boolean} allowInheritProto - to enable inherited protocol (//), or otherwise, only http:// and https:// are allowed
* @param {boolean} allowRelPath - to allow relative path
* @param {boolean} allowHosts - an optional array of hostnames that each matches /^[\w\.-]+$/. If any one is found unmatched, return null
* @param {boolean} reqHtmlDecode - to run html decoding first before applying the tests
* @returns {function|null} the yuwl filter that tests value according to the config
*/
function yuwlFactory (allowAllSafeURIs, allowInheritProto, allowRelPath, allowHosts, reqHtmlDecode) {
var i, n, reHost, reHosts,
reProto = allowAllSafeURIs ?
/^[\x00-\x20]*(?:(?:(blob:)?https?|ftp):\/\/|data:image\/(?:gif|jpe?g|png);base64,|\/\/)/i :
allowInheritProto ?
/^[\x00-\x20]*(?:https?:\/\/|\/\/)/i :
/^[\x00-\x20]*https?:\/\//i,
reRelPath = allowRelPath && /^[\x00-\x20]*(?![a-z][a-z0-9+-.]*:|[\/\\]{2})/i;

// create reHosts from the hostList array, that is case insensitive
// reHosts is defined as must start with either of the allowed hosts, and
// followed by either nothing (i.e., end of string), or / ? # \
// return null if there exists an host not fullfilling the regexp /^[\w\.-]+$/
if (allowHosts) {
reHost = /^[\w\.-]+$/;
for (i = 0, n = allowHosts.length; i < n; i++) {
if (!reHost.test(allowHosts[i])) {
return null;
}
}
reHosts = new RegExp('^(?:' +
allowHosts.join('|').replace(/\./g, '\\.') +
')(?:$|[\\/?#\\\\])', 'i');
}

return function(url) {
if (reqHtmlDecode) {
url = htmlDecode(url);
}
// either its a relativeURL, or
// its protocol is allowed, and no host restrictions, or
// its protocol and host is both allowed
if ((allowRelPath && reRelPath.test(url)) ||
((result = reProto.exec(url)) !== null &&
(!reHosts || (reHosts && reHosts.test(url.slice(result[0].length)))))) {
return url;
}
return 'x-' + url;
};
}


function cssEncode(chr) {
Expand All @@ -270,6 +321,8 @@ exports._getPrivFilters = function () {
}

return (x = {
yuwl: null,
yuwlFactory: yuwlFactory,
yHtmlDecode: htmlDecode,
/*
* @param {string} s - An untrusted uri input
Expand Down

0 comments on commit 2767614

Please sign in to comment.