This filter is a fallback to use the standard HTML escaping (i.e., encoding &<>"') - * in contexts that are currently not handled by the automatic context-sensitive templating solution.
- * - * Workaround this problem by following the suggestion below: - * Use - * and retrieve your data with document.getElementById('strJS').value. - * - */ -exports.y = function(s) { - return typeof s === STR_UD ? STR_UD - : s === null ? STR_NL - : s.toString() - .replace(SPECIAL_HTML_CHARS, function (m) { - if (m === '&') { return '&'; } - if (m === '<') { return '<'; } - if (m === '>') { return '>'; } - if (m === '"') { return '"'; } - /* if (m === "'") */ return '''; - }); -}; - - -// FOR DETAILS, refer to inHTMLData() -// Reference: https://html.spec.whatwg.org/multipage/syntax.html#data-state -exports.yd = function (s) { - return typeof s === STR_UD ? STR_UD - : s === null ? STR_NL - : s.toString() - .replace(LT, '<'); -}; - - -var COMMENT_SENSITIVE_CHARS = /(--!?>|--?!?$|\]>|\]$)/g; -// FOR DETAILS, refer to inHTMLComment() -// '-->' and '--!>' are modified as '-- >' and '--! >' so as stop comment state breaking -// for string ends with '--!', '--', or '-' are appended with a space, so as to stop collaborative state breaking at {{s}}>, {{s}}!>, {{s}}-> -// Reference: https://html.spec.whatwg.org/multipage/syntax.html#comment-state -// ']>' and 'ends with ]' patterns deal with IE conditional comments. verified in IE that '] >' can stop that. -// Reference: http://msdn.microsoft.com/en-us/library/ms537512%28v=vs.85%29.aspx -exports.yc = function (s) { - return typeof s === STR_UD ? STR_UD - : s === null ? STR_NL - : s.toString() - .replace(COMMENT_SENSITIVE_CHARS, function(m){ - if (m === '-->') { return '-- >'; } - if (m === '--!>') { return '--! >'; } - if (m === '--!') { return '--! '; } - if (m === '--') { return '-- '; } - if (m === '-') { return '- '; } - if (m === ']>') { return '] >'; } - /*if (m === ']')*/ return '] '; - }); -}; - -// Reference: https://html.spec.whatwg.org/multipage/syntax.html#before-attribute-value-state -var BEFORE_ATTR_VALUE_CHARS = /^["']/; -var ATTR_VALUE_UNQUOTED_CHARS = /[\t\n\f >]/g; - -// FOR DETAILS, refer to inDoubleQuotedAttr() -// Reference: https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(double-quoted)-state -exports.yavd = function (s) { - return typeof s === STR_UD ? STR_UD - : s === null ? STR_NL - : s.toString() - .replace(QUOT, '"'); -}; - -// FOR DETAILS, refer to inSingleQuotedAttr() -// Reference: https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(single-quoted)-state -exports.yavs = function (s) { - return typeof s === STR_UD ? STR_UD - : s === null ? STR_NL - : s.toString() - .replace(SQUOT, '''); -}; - -// FOR DETAILS, refer to inUnQuotedAttr() -// Reference: https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(unquoted)-state -// Reference: https://html.spec.whatwg.org/multipage/syntax.html#before-attribute-value-state -exports.yavu = function (s) { - if (typeof s === STR_UD) return STR_UD; - if (s === null) return STR_NL; - - s = s.toString().replace(ATTR_VALUE_UNQUOTED_CHARS, function (m) { - if (m === '\t') { return '	'; } - if (m === '\n') { return '
'; } - if (m === '\f') { return ''; } // in hex: 0C - if (m === ' ') { return ' '; } // in hex: 20 - /*if (m === '>')*/ return '>'; - }); - - // if s starts with ' or ", encode it resp. as ' or " to enforce the attr value (unquoted) state - // if instead starts with some whitespaces [\t\n\f ] then optionally a quote, - // then the above encoding has already enforced the attr value (unquoted) state - // therefore, no need to encode the quote - // Reference: https://html.spec.whatwg.org/multipage/syntax.html#before-attribute-value-state - s = s.replace(BEFORE_ATTR_VALUE_CHARS, function (m) { - if (m === '"') { return '"'; } - /*if (m === "'")*/ return '''; - }); - - // Inject NULL character if an empty string is encountered in - // unquoted attribute value state. - // - // Example: - // - // - // Rationale 1: our belief is that developers wouldn't expect an - // empty string would result in ' name="firstname"' rendered as - // attribute value, even though this is how HTML5 is specified. - // Rationale 2: an empty string can effectively alter its immediate - // subsequent state, which violates our design principle. As per - // the HTML 5 spec, NULL or \u0000 is the magic character to end - // the comment state, which therefore will not mess up later - // contexts. - // Reference: https://html.spec.whatwg.org/multipage/syntax.html#before-attribute-value-state - return (s === '') ? '\u0000' : s; -}; - -exports.yu = encodeURI; -exports.yuc = encodeURIComponent; - -// Reference: https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Null_breaks_up_JavaScript_directive -// Reference: https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Embedded_newline_to_break_up_XSS -// Reference: https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference -// Reference for named characters: https://html.spec.whatwg.org/multipage/entities.json -/* -var URI_BLACKLIST_INTERIM_WHITESPACE = [ - '(?:', - [ - // encodeURI/encodeURIComponent has percentage encoded ASCII chars of decimal 0-32 - // '\u0000', - // '\t', '\n', '\r', // tab, newline, carriage return - '[xX]0*[9aAdD];?', // , , in hex - '*(?:9|10|13);?', // , , in dec - '	', '
' // tab, newline in char entities - ].join('|'), - ')*' -].join(''); - -// delay building the following as an RegExp() object until the first hit -var URI_BLACKLIST, URI_BLACKLIST_REGEXPSTR = [ - - // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Spaces_and_meta_chars_before_the_JavaScript_in_images_for_XSS - '^(?:', - [ - // encodeURI/encodeURIComponent has percentage encoded ASCII chars of decimal 0-32 - // '\u0001', '\u0002', '\u0003', '\u0004', - // '\u0005', '\u0006', '\u0007', '\u0008', - // '\u0009', '\u000A', '\u000B', '\u000C', - // '\u000D', '\u000E', '\u000F', '\u0010', - // '\u0011', '\u0012', '\u0013', '\u0014', - // '\u0015', '\u0016', '\u0017', '\u0018', - // '\u0019', '\u001A', '\u001B', '\u001C', - // '\u001D', '\u001E', '\u001F', '\u0020', - '[xX]0*(?:1?[1-9a-fA-F]|10|20);?', // -20 in hex - '*(?:[1-9]|[1-2][0-9]|30|31|32);?', // -32 in dec - '	', '
' // space, newline in char entities - - ].join('|'), - ')*', - - - // java java java - // JAVA JAVA JAVA - // vb vb vb - // VB VB VB - // script script script - // SCRIPT SCRIPT SCRIPT - // : : : - - // java|vb - '(?:', - [ - // java - [ - '(?:j|J|[xX]0*(?:6|4)[aA];?|*(?:106|74);?)', - '(?:a|A|[xX]0*(?:6|4)1;?|*(?:97|65);?)', - '(?:v|V|[xX]0*(?:7|5)6;?|*(?:118|86);?)', - '(?:a|A|[xX]0*(?:6|4)1;?|*(?:97|65);?)', - - ].join(URI_BLACKLIST_INTERIM_WHITESPACE), - // vb - [ - '(?:v|V|[xX]0*(?:7|5)6;?|*(?:118|86);?)', - '(?:b|B|[xX]0*(?:6|4)2;?|*(?:98|66);?)' - - ].join(URI_BLACKLIST_INTERIM_WHITESPACE) - - ].join('|'), - ')', - - URI_BLACKLIST_INTERIM_WHITESPACE, - - // script: - [ - '(?:s|S|[xX]0*(?:7|5)3;?|*(?:115|83);?)', - '(?:c|C|[xX]0*(?:6|4)3;?|*(?:99|67);?)', - '(?:r|R|[xX]0*(?:7|5)2;?|*(?:114|82);?)', - '(?:i|I|[xX]0*(?:6|4)9;?|*(?:105|73);?)', - '(?:p|P|[xX]0*(?:7|5)0;?|*(?:112|80);?)', - '(?:t|T|[xX]0*(?:7|5)4;?|*(?:116|84);?)', - '(?:\:|[xX]0*3[aA];?|*58;?)' - - ].join(URI_BLACKLIST_INTERIM_WHITESPACE) -].join(''); -*/ - -var URI_SLOWLANE = ['&', 'j', 'J', 'v', 'V'], - URI_BLACKLIST = null, - // delay building URI_BLACKLIST as an RegExp() object until the first hit - // the following str is generated by the above commented logic - URI_BLACKLIST_REGEXPSTR = "^(?:[xX]0*(?:1?[1-9a-fA-F]|10|20);?|*(?:[1-9]|[1-2][0-9]|30|31|32);?|	|
)*(?:(?:j|J|[xX]0*(?:6|4)[aA];?|*(?:106|74);?)(?:[xX]0*[9aAdD];?|*(?:9|10|13);?|	|
)*(?:a|A|[xX]0*(?:6|4)1;?|*(?:97|65);?)(?:[xX]0*[9aAdD];?|*(?:9|10|13);?|	|
)*(?:v|V|[xX]0*(?:7|5)6;?|*(?:118|86);?)(?:[xX]0*[9aAdD];?|*(?:9|10|13);?|	|
)*(?:a|A|[xX]0*(?:6|4)1;?|*(?:97|65);?)|(?:v|V|[xX]0*(?:7|5)6;?|*(?:118|86);?)(?:[xX]0*[9aAdD];?|*(?:9|10|13);?|	|
)*(?:b|B|[xX]0*(?:6|4)2;?|*(?:98|66);?))(?:[xX]0*[9aAdD];?|*(?:9|10|13);?|	|
)*(?:s|S|[xX]0*(?:7|5)3;?|*(?:115|83);?)(?:[xX]0*[9aAdD];?|*(?:9|10|13);?|	|
)*(?:c|C|[xX]0*(?:6|4)3;?|*(?:99|67);?)(?:[xX]0*[9aAdD];?|*(?:9|10|13);?|	|
)*(?:r|R|[xX]0*(?:7|5)2;?|*(?:114|82);?)(?:[xX]0*[9aAdD];?|*(?:9|10|13);?|	|
)*(?:i|I|[xX]0*(?:6|4)9;?|*(?:105|73);?)(?:[xX]0*[9aAdD];?|*(?:9|10|13);?|	|
)*(?:p|P|[xX]0*(?:7|5)0;?|*(?:112|80);?)(?:[xX]0*[9aAdD];?|*(?:9|10|13);?|	|
)*(?:t|T|[xX]0*(?:7|5)4;?|*(?:116|84);?)(?:[xX]0*[9aAdD];?|*(?:9|10|13);?|	|
)*(?::|[xX]0*3[aA];?|*58;?)"; - -/* - * ============================= - * Rationale on data: protocol - * ============================= - * Given there're two execution possibilities: - * 1. data:text/html, in <(i)frame>'s src - * expected script execution but it's of a different origin than the included page. hence not CROSS-SITE scripting - * 2. data:application/javascript,alert(1) or data:,alert(1) in in <(i)frame>'s src - * expected script execution but it's of a different origin than the included page. hence not CROSS-SITE scripting - * 2. data:application/javascript,alert(1) or data:,alert(1) in in <(i)frame>'s src + * expected script execution but it's of a different origin than the included page. hence not CROSS-SITE scripting + * 2. data:application/javascript,alert(1) or data:,alert(1) in