[XSS] Precomputed invalid identifier chars regular expression.
This commit is contained in:
parent
7abdd20155
commit
2cdbbe2d57
|
@ -33,4 +33,37 @@ if (UA.isMozilla) {
|
||||||
() => y("https://vulnerabledoma.in/xss_link?url=javascript:\\u{%0A6e}ame"),
|
() => y("https://vulnerabledoma.in/xss_link?url=javascript:\\u{%0A6e}ame"),
|
||||||
].map(t => Test.run(t))
|
].map(t => Test.run(t))
|
||||||
).then(() => Test.report());
|
).then(() => Test.report());
|
||||||
|
|
||||||
|
let invalidCharsTest = async () => {
|
||||||
|
|
||||||
|
await include("xss/InjectionChecker.js");
|
||||||
|
let IC = await XSS.InjectionChecker;
|
||||||
|
let rx = new IC().invalidCharsRx;
|
||||||
|
|
||||||
|
let x = n => '\\u' + ("0000" + n.toString(16)).slice(-4);
|
||||||
|
function check(ch) {
|
||||||
|
eval(`{let _${ch}_}`);
|
||||||
|
}
|
||||||
|
let cur = 0x7e;
|
||||||
|
let fail = false;
|
||||||
|
while (cur++ < 0xffff) {
|
||||||
|
let ch = String.fromCharCode(cur);
|
||||||
|
try {
|
||||||
|
check(ch);
|
||||||
|
if (tx.test(ch)) {
|
||||||
|
console.error(x(cur) + " should not test invalid!");
|
||||||
|
fail = true;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (!/illegal char/.test(e.message)) continue;
|
||||||
|
if (!rx.test(ch)) {
|
||||||
|
console.error(x(cur) + " must test invalid!");
|
||||||
|
fail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !fail;
|
||||||
|
};
|
||||||
|
|
||||||
|
Test.run(invalidCharsTest, "InjectionChecker.invalidCharsRx").then(Test.report());
|
||||||
}
|
}
|
||||||
|
|
|
@ -492,43 +492,8 @@ XSS.InjectionChecker = (async () => {
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
|
|
||||||
_createInvalidRanges: function() {
|
// see https://mathiasbynens.be/notes/javascript-identifiers-es6#acceptable-unicode-symbols
|
||||||
function x(n) {
|
invalidCharsRx: /^[^"'`/<>]*[^$_\p{ID_Start}\p{ID_Continue}\u200c\u200d]/u,
|
||||||
return '\\u' + ("0000" + n.toString(16)).slice(-4);
|
|
||||||
}
|
|
||||||
|
|
||||||
let chunks = [];
|
|
||||||
let first = -1;
|
|
||||||
let last = -1;
|
|
||||||
let cur = 0x7e;
|
|
||||||
while (cur++ <= 0xffff) {
|
|
||||||
try {
|
|
||||||
Function("let _" + String.fromCharCode(cur));
|
|
||||||
} catch (e) {
|
|
||||||
if (!/illegal char/.test(e.message)) continue;
|
|
||||||
if (first == -1) {
|
|
||||||
first = last = cur;
|
|
||||||
chunks.push(x(cur));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (cur - last == 1) {
|
|
||||||
last = cur;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last != first) chunks.push(`-${x(last)}`);
|
|
||||||
chunks.push(x(cur));
|
|
||||||
last = first = cur;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return chunks.join('');
|
|
||||||
},
|
|
||||||
|
|
||||||
get invalidCharsRx() {
|
|
||||||
let value = new RegExp("^[^\"'`/<>]*[" + this._createInvalidRanges() + "]");
|
|
||||||
Object.defineProperty(Object.getPrototypeOf(this), 'invalidCharsRx', {value});
|
|
||||||
return value;
|
|
||||||
},
|
|
||||||
|
|
||||||
async checkJSBreak(s) {
|
async checkJSBreak(s) {
|
||||||
// Direct script injection breaking JS string literals or comments
|
// Direct script injection breaking JS string literals or comments
|
||||||
|
|
Loading…
Reference in New Issue