forked from svrjs/svrjs
Optimize URL sanitizer
This commit is contained in:
parent
7fe503c07d
commit
82b0510774
1 changed files with 23 additions and 16 deletions
|
@ -1,43 +1,50 @@
|
||||||
// SVR.JS path sanitizer function
|
// SVR.JS path sanitizer function
|
||||||
function sanitizeURL(resource, allowDoubleSlashes) {
|
function sanitizeURL(resource, allowDoubleSlashes) {
|
||||||
if (resource == "*" || resource == "") return resource;
|
if (resource === "*" || resource === "") return resource;
|
||||||
|
|
||||||
// Remove null characters
|
// Remove null characters
|
||||||
resource = resource.replace(/%00|\0/g, "");
|
resource = resource.replace(/%00|\0/g, "");
|
||||||
|
|
||||||
// Check if URL is malformed (e.g. %c0%af or %u002f or simply %as)
|
// Check if URL is malformed (e.g. %c0%af or %u002f or simply %as)
|
||||||
if (resource.match(/%(?:c[01]|f[ef]|(?![0-9a-f]{2}).{2}|.{0,1}$)/i))
|
if (resource.match(/%(?:c[01]|f[ef]|(?![0-9a-f]{2}).{2}|.{0,1}$)/i))
|
||||||
throw new URIError("URI malformed");
|
throw new URIError("URI malformed");
|
||||||
|
|
||||||
// Decode URL-encoded characters while preserving certain characters
|
// Decode URL-encoded characters while preserving certain characters
|
||||||
resource = resource.replace(/%([0-9a-f]{2})/gi, (match, hex) => {
|
resource = resource.replace(/%([0-9a-f]{2})/gi, (match, hex) => {
|
||||||
const decodedChar = String.fromCharCode(parseInt(hex, 16));
|
const decodedChar = String.fromCharCode(parseInt(hex, 16));
|
||||||
return /(?!["<>^`{|}?#%])[!-~]/.test(decodedChar) ? decodedChar : "%" + hex;
|
return /[!$&-;=@-\]_a-z~]/.test(decodedChar) ? decodedChar : match;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Encode certain characters
|
// Encode certain characters
|
||||||
resource = resource.replace(/[<>^`{|}]]/g, (character) => {
|
resource = resource.replace(/[<>^`{|}]/g, (character) => {
|
||||||
const charCode = character.charCodeAt(0);
|
const charCode = character.charCodeAt(0);
|
||||||
return (
|
return (
|
||||||
"%" + (charCode < 16 ? "0" : "") + charCode.toString(16).toUpperCase()
|
"%" + (charCode < 16 ? "0" : "") + charCode.toString(16).toUpperCase()
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
let sanitizedResource = resource;
|
|
||||||
// Ensure the resource starts with a slash
|
// Ensure the resource starts with a slash
|
||||||
if (resource[0] != "/") sanitizedResource = "/" + sanitizedResource;
|
if (resource[0] !== "/") resource = "/" + resource;
|
||||||
|
|
||||||
// Convert backslashes to slashes and handle duplicate slashes
|
// Convert backslashes to slashes and handle duplicate slashes
|
||||||
sanitizedResource = sanitizedResource
|
resource = resource
|
||||||
.replace(/\\/g, "/")
|
.replace(/\\/g, "/")
|
||||||
.replace(allowDoubleSlashes ? /\/{3,}/g : /\/+/g, "/");
|
.replace(allowDoubleSlashes ? /\/{3,}/g : /\/+/g, "/");
|
||||||
// Handle relative navigation (e.g., "/./", "/../", "../", "./"), also remove trailing dots in paths
|
|
||||||
sanitizedResource = sanitizedResource
|
// Handle relative navigation (e.g., "/./", "/../", "../", "./") and remove trailing dots in paths
|
||||||
|
resource = resource
|
||||||
.replace(/\/\.(?:\.{2,})?(?=\/|$)/g, "")
|
.replace(/\/\.(?:\.{2,})?(?=\/|$)/g, "")
|
||||||
.replace(/([^./])\.+(?=\/|$)/g, "$1");
|
.replace(/([^./])\.+(?=\/|$)/g, "$1");
|
||||||
while (sanitizedResource.match(/\/(?!\.\.\/)[^/]+\/\.\.(?=\/|$)/)) {
|
|
||||||
sanitizedResource = sanitizedResource.replace(
|
// Remove remaining "../"
|
||||||
/\/(?!\.\.\/)[^/]+\/\.\.(?=\/|$)/g,
|
while (resource.match(/\/(?!\.\.\/)[^/]+\/\.\.(?=\/|$)/)) {
|
||||||
"",
|
resource = resource.replace(/\/(?!\.\.\/)[^/]+\/\.\.(?=\/|$)/g, "");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
sanitizedResource = sanitizedResource.replace(/\/\.\.(?=\/|$)/g, "");
|
resource = resource.replace(/\/\.\.(?=\/|$)/g, "");
|
||||||
if (sanitizedResource.length == 0) return "/";
|
|
||||||
else return sanitizedResource;
|
// If the result has length of 0, return "/", else return the sanitized URL
|
||||||
|
if (resource.length == 0) return "/";
|
||||||
|
else return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = sanitizeURL;
|
module.exports = sanitizeURL;
|
||||||
|
|
Reference in a new issue