[XSS] Fixed performance regression in invalid character ranges generation causing random XSS "DOS" false positives.

This commit is contained in:
hackademix 2021-12-25 00:16:09 +01:00
parent bd7b621109
commit fdaa8fce27
1 changed files with 9 additions and 11 deletions

View File

@ -493,18 +493,18 @@ XSS.InjectionChecker = (async () => {
return '\\u' + ("0000" + n.toString(16)).slice(-4); return '\\u' + ("0000" + n.toString(16)).slice(-4);
} }
var ret = ""; let chunks = [];
var first = -1; let first = -1;
var last = -1; let last = -1;
var cur = 0x7e; let cur = 0x7e;
while (cur++ <= 0xffff) { while (cur++ <= 0xffff) {
try { try {
eval("var _" + String.fromCharCode(cur) + "_=1"); Function("let _" + String.fromCharCode(cur));
} catch (e) { } catch (e) {
if (!/illegal char/.test(e.message)) continue; if (!/illegal char/.test(e.message)) continue;
if (first == -1) { if (first == -1) {
first = last = cur; first = last = cur;
ret += x(cur); chunks.push(x(cur));
continue; continue;
} }
if (cur - last == 1) { if (cur - last == 1) {
@ -512,12 +512,12 @@ XSS.InjectionChecker = (async () => {
continue; continue;
} }
if (last != first) ret += "-" + x(last); if (last != first) chunks.push(`-${x(last)}`);
ret += x(cur); chunks.push(x(cur));
last = first = cur; last = first = cur;
} }
} }
return ret; return chunks.join('');
}, },
get invalidCharsRx() { get invalidCharsRx() {
@ -528,7 +528,6 @@ XSS.InjectionChecker = (async () => {
async checkJSBreak(s) { async checkJSBreak(s) {
// Direct script injection breaking JS string literals or comments // Direct script injection breaking JS string literals or comments
// preliminarily cleanup most urlencoded noise and reduce JSON/XML // preliminarily cleanup most urlencoded noise and reduce JSON/XML
s = ';' + this.reduceXML(await this.reduceJSON(this.collapseChars( s = ';' + this.reduceXML(await this.reduceJSON(this.collapseChars(
s.replace(/\%\d+[a-z\(]\w*/gi, '§') s.replace(/\%\d+[a-z\(]\w*/gi, '§')
@ -775,7 +774,6 @@ XSS.InjectionChecker = (async () => {
async checkJS(s, unescapedUni) { async checkJS(s, unescapedUni) {
this.log(s); this.log(s);
if (/[=\(](?:[\s\S]*(?:\?name\b[\s\S]*:|[^&?]\bname\b)|name\b)/.test(s)) { if (/[=\(](?:[\s\S]*(?:\?name\b[\s\S]*:|[^&?]\bname\b)|name\b)/.test(s)) {
this.nameAssignment = true; this.nameAssignment = true;
} }