@@ -24,6 +24,7 @@ XSS.InjectionChecker = (async () => {
2424 "/nscl/common/Base64.js" ,
2525 "/nscl/common/AsyncRegExp.js" ,
2626 "/nscl/common/DebuggableRegExp.js" ,
27+ "/nscl/common/RegExpCombo.js" ,
2728 "/nscl/common/Timing.js" ,
2829 "/xss/ASPIdiocy.js" ,
2930 "/lib/he.js" ]
@@ -886,13 +887,20 @@ XSS.InjectionChecker = (async () => {
886887 return false ;
887888 } ,
888889
889- AttributesChecker : new RegExp (
890- "(?:\\W|^)(?:javascript:(?:[^]+[=\\\\\\(`\\[\\.<]|[^]*(?:\\bname\\b|\\\\[ux]\\d))|" +
891- "data:(?:(?:[a-z]\\w+/\\w[\\w+-]+\\w)?[;,]|[^]*;[^]*\\b(?:base64|charset=)|[^]*,[^]*<[^]*\\w[^]*>))|@" +
892- ( "import\\W*(?:\\/\\*[^]*)?(?:[\"']|url[^]*\\()" +
893- "|-moz-binding[^]*:[^]*url[^]*\\(|\\{\\{[^]+\\}\\}" )
894- . replace ( / [ a - r t - z \- ] / g, "\\W*$&" ) ,
895- "i" ) ,
890+ AttributesChecker : RegExp . combo (
891+ / (?: \W | ^ ) / i, // beginning or after non-space
892+ '(?:' ,
893+ // executable URLs
894+ / j a v a s c r i p t : (?: [ ^ ] + [ = \\ \( ` \[ \. < ] | [ ^ ] * (?: \b n a m e \b | \\ [ u x ] \d ) ) / ,
895+ / | d a t a : (?: (?: [ a - z ] \w + \/ \w [ \w + - ] + \w ) ? [ ; , ] | [ ^ ] * ; [ ^ ] * \b (?: b a s e 6 4 | c h a r s e t = ) | [ ^ ] * , [ ^ ] * < [ ^ ] * \w [ ^ ] * > ) / ,
896+ ')|' ,
897+ // CSS injection
898+ / @ i m p o r t \W * (?: \/ \* [ ^ ] * ) ? (?: [ " ' ] | u r l [ ^ ] * \( ) | - m o z - b i n d i n g [ ^ ] * : [ ^ ] * u r l [ ^ ] * \( /
899+ . source . replace ( / [ @ a - r t - z \- ] / g, "\\W*$&" ) , // fuzzify keywords
900+ // potential JS fragmentation in client-side template framework
901+ / | (?: \{ \{ [ ^ ] * \S [ ^ ] * } } [ ^ ] * ) { 2 , } /
902+ ) ,
903+
896904 async checkAttributes ( s ) {
897905 s = this . reduceDashPlus ( s ) ;
898906 if ( this . _rxCheck ( "Attributes" , s ) ) return true ;
0 commit comments