UNPKG

45.7 kBJavaScriptView Raw
1/*
2Copyright (c) 2015, Yahoo! Inc. All rights reserved.
3Copyrights licensed under the New BSD License.
4See the accompanying LICENSE file for terms.
5
6Authors: Nera Liu <neraliu@yahoo-inc.com>
7 Adonis Fung <adon@yahoo-inc.com>
8 Albert Yu <albertyu@yahoo-inc.com>
9*/
10/*jshint node: true */
11
12exports._getPrivFilters = function () {
13
14 var STR_UD = 'undefined',
15 STR_NL = 'null',
16 LT = /</g,
17 QUOT = /\"/g,
18 SQUOT = /\'/g,
19 SPECIAL_HTML_CHARS = /[&<>"'`]/g;
20
21 var COMMENT_SENSITIVE_CHARS = /(--!?>|--?!?$|\]>|\]$)/g;
22
23 // Reference: https://html.spec.whatwg.org/multipage/syntax.html#before-attribute-value-state
24 var BEFORE_ATTR_VALUE_CHARS = /^["'`]/;
25 var ATTR_VALUE_UNQUOTED_CHARS = /[\t\n\f >]/g;
26
27 // Reference: https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Null_breaks_up_JavaScript_directive
28 // Reference: https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Embedded_newline_to_break_up_XSS
29 // Reference: https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference
30 // Reference for named characters: https://html.spec.whatwg.org/multipage/entities.json
31 /*
32 var URI_BLACKLIST_INTERIM_WHITESPACE = [
33 '(?:',
34 [
35 // encodeURI/encodeURIComponent has percentage encoded ASCII chars of decimal 0-32
36 // '\u0000',
37 // '\t', '\n', '\r', // tab, newline, carriage return
38 '&#[xX]0*[9aAdD];?', // &#x9, &#xA, &#xD in hex
39 '&#0*(?:9|10|13);?', // &#9, &#10, &#13 in dec
40 '&Tab;', '&NewLine;' // tab, newline in char entities
41 ].join('|'),
42 ')*'
43 ].join('');
44
45 // delay building the following as an RegExp() object until the first hit
46 var URI_BLACKLIST, URI_BLACKLIST_REGEXPSTR = [
47
48 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Spaces_and_meta_chars_before_the_JavaScript_in_images_for_XSS
49 '^(?:',
50 [
51 // encodeURI/encodeURIComponent has percentage encoded ASCII chars of decimal 0-32
52 // '\u0001', '\u0002', '\u0003', '\u0004',
53 // '\u0005', '\u0006', '\u0007', '\u0008',
54 // '\u0009', '\u000A', '\u000B', '\u000C',
55 // '\u000D', '\u000E', '\u000F', '\u0010',
56 // '\u0011', '\u0012', '\u0013', '\u0014',
57 // '\u0015', '\u0016', '\u0017', '\u0018',
58 // '\u0019', '\u001A', '\u001B', '\u001C',
59 // '\u001D', '\u001E', '\u001F', '\u0020',
60 '&#[xX]0*(?:1?[1-9a-fA-F]|10|20);?', // &#x1-20 in hex
61 '&#0*(?:[1-9]|[1-2][0-9]|30|31|32);?', // &#1-32 in dec
62 '&Tab;', '&NewLine;' // space, newline in char entities
63
64 ].join('|'),
65 ')*',
66
67
68 // &#x6A;&#x61;&#x76;&#x61; &#106&#97&#118&#97 java
69 // &#x4A;&#x41;&#x56;&#x41; &#74&#65&#86&#65 JAVA
70 // &#x76;&#x62; &#118&#98 vb
71 // &#x56;&#x42; &#86&#66 VB
72 // &#x73;&#x63;&#x72;&#x69;&#x70;&#x74; &#115&#99&#114&#105&#112&#116 script
73 // &#x53;&#x43;&#x52;&#x49;&#x50;&#x54; &#83&#67&#82&#73&#80&#84 SCRIPT
74 // &#x3A; &#58 :
75
76 // java|vb
77 '(?:',
78 [
79 // java
80 [
81 '(?:j|J|&#[xX]0*(?:6|4)[aA];?|&#0*(?:106|74);?)',
82 '(?:a|A|&#[xX]0*(?:6|4)1;?|&#0*(?:97|65);?)',
83 '(?:v|V|&#[xX]0*(?:7|5)6;?|&#0*(?:118|86);?)',
84 '(?:a|A|&#[xX]0*(?:6|4)1;?|&#0*(?:97|65);?)',
85
86 ].join(URI_BLACKLIST_INTERIM_WHITESPACE),
87 // vb
88 [
89 '(?:v|V|&#[xX]0*(?:7|5)6;?|&#0*(?:118|86);?)',
90 '(?:b|B|&#[xX]0*(?:6|4)2;?|&#0*(?:98|66);?)'
91
92 ].join(URI_BLACKLIST_INTERIM_WHITESPACE)
93
94 ].join('|'),
95 ')',
96
97 URI_BLACKLIST_INTERIM_WHITESPACE,
98
99 // script:
100 [
101 '(?:s|S|&#[xX]0*(?:7|5)3;?|&#0*(?:115|83);?)',
102 '(?:c|C|&#[xX]0*(?:6|4)3;?|&#0*(?:99|67);?)',
103 '(?:r|R|&#[xX]0*(?:7|5)2;?|&#0*(?:114|82);?)',
104 '(?:i|I|&#[xX]0*(?:6|4)9;?|&#0*(?:105|73);?)',
105 '(?:p|P|&#[xX]0*(?:7|5)0;?|&#0*(?:112|80);?)',
106 '(?:t|T|&#[xX]0*(?:7|5)4;?|&#0*(?:116|84);?)',
107 '(?::|&#[xX]0*3[aA];?|&#0*58;?|&colon;)'
108
109 ].join(URI_BLACKLIST_INTERIM_WHITESPACE)
110 ].join('');
111 */
112
113 var URI_SLOWLANE = ['&', 'j', 'J', 'v', 'V'],
114 // delay building URI_BLACKLIST as an RegExp() object until the first hit
115 // the following str is generated by the above commented logic
116 URI_BLACKLIST_REGEXP = /^(?:&#[xX]0*(?:1?[1-9a-fA-F]|10|20);?|&#0*(?:[1-9]|[1-2][0-9]|30|31|32);?|&Tab;|&NewLine;)*(?:(?:j|J|&#[xX]0*(?:6|4)[aA];?|&#0*(?:106|74);?)(?:&#[xX]0*[9aAdD];?|&#0*(?:9|10|13);?|&Tab;|&NewLine;)*(?:a|A|&#[xX]0*(?:6|4)1;?|&#0*(?:97|65);?)(?:&#[xX]0*[9aAdD];?|&#0*(?:9|10|13);?|&Tab;|&NewLine;)*(?:v|V|&#[xX]0*(?:7|5)6;?|&#0*(?:118|86);?)(?:&#[xX]0*[9aAdD];?|&#0*(?:9|10|13);?|&Tab;|&NewLine;)*(?:a|A|&#[xX]0*(?:6|4)1;?|&#0*(?:97|65);?)|(?:v|V|&#[xX]0*(?:7|5)6;?|&#0*(?:118|86);?)(?:&#[xX]0*[9aAdD];?|&#0*(?:9|10|13);?|&Tab;|&NewLine;)*(?:b|B|&#[xX]0*(?:6|4)2;?|&#0*(?:98|66);?))(?:&#[xX]0*[9aAdD];?|&#0*(?:9|10|13);?|&Tab;|&NewLine;)*(?:s|S|&#[xX]0*(?:7|5)3;?|&#0*(?:115|83);?)(?:&#[xX]0*[9aAdD];?|&#0*(?:9|10|13);?|&Tab;|&NewLine;)*(?:c|C|&#[xX]0*(?:6|4)3;?|&#0*(?:99|67);?)(?:&#[xX]0*[9aAdD];?|&#0*(?:9|10|13);?|&Tab;|&NewLine;)*(?:r|R|&#[xX]0*(?:7|5)2;?|&#0*(?:114|82);?)(?:&#[xX]0*[9aAdD];?|&#0*(?:9|10|13);?|&Tab;|&NewLine;)*(?:i|I|&#[xX]0*(?:6|4)9;?|&#0*(?:105|73);?)(?:&#[xX]0*[9aAdD];?|&#0*(?:9|10|13);?|&Tab;|&NewLine;)*(?:p|P|&#[xX]0*(?:7|5)0;?|&#0*(?:112|80);?)(?:&#[xX]0*[9aAdD];?|&#0*(?:9|10|13);?|&Tab;|&NewLine;)*(?:t|T|&#[xX]0*(?:7|5)4;?|&#0*(?:116|84);?)(?:&#[xX]0*[9aAdD];?|&#0*(?:9|10|13);?|&Tab;|&NewLine;)*(?::|&#[xX]0*3[aA];?|&#0*58;?|&colon;)/;
117
118 // Given a full URI, need to support "[" ( IPv6address ) "]" in URI as per RFC3986
119 // Reference: https://tools.ietf.org/html/rfc3986
120 var URL_IPV6 = /\/\/%5[Bb]([A-Fa-f0-9:]+)%5[Dd]/;
121
122 return {
123 /*
124 * @param {string} s - An untrusted user input
125 * @returns {string} s - The original user input with & < > " ' ` encoded respectively as &amp; &lt; &gt; &quot; &#39; and &#96;.
126 *
127 * @description
128 * <p>This filter is a fallback to use the standard HTML escaping (i.e., encoding &<>"'`)
129 * in contexts that are currently not handled by the automatic context-sensitive templating solution.</p>
130 *
131 * Workaround this problem by following the suggestion below:
132 * Use <input id="strJS" value="{{xssFilters.inHTMLData(data)}}">
133 * and retrieve your data with document.getElementById('strJS').value.
134 *
135 */
136 y: function(s) {
137 return typeof s === STR_UD ? STR_UD
138 : s === null ? STR_NL
139 : s.toString()
140 .replace(SPECIAL_HTML_CHARS, function (m) {
141 if (m === '&') { return '&amp;'; }
142 if (m === '<') { return '&lt;'; }
143 if (m === '>') { return '&gt;'; }
144 if (m === '"') { return '&quot;'; }
145 if (m === "'") { return '&#39;'; }
146 /*if (m === '`')*/ return '&#96;'; // in hex: 60
147 });
148 },
149
150 // FOR DETAILS, refer to inHTMLData()
151 // Reference: https://html.spec.whatwg.org/multipage/syntax.html#data-state
152 yd: function (s) {
153 return typeof s === STR_UD ? STR_UD
154 : s === null ? STR_NL
155 : s.toString()
156 .replace(LT, '&lt;');
157 },
158
159 // FOR DETAILS, refer to inHTMLComment()
160 // '-->' and '--!>' are modified as '-- >' and '--! >' so as stop comment state breaking
161 // for string ends with '--!', '--', or '-' are appended with a space, so as to stop collaborative state breaking at {{s}}>, {{s}}!>, {{s}}->
162 // Reference: https://html.spec.whatwg.org/multipage/syntax.html#comment-state
163 // ']>' and 'ends with ]' patterns deal with IE conditional comments. verified in IE that '] >' can stop that.
164 // Reference: http://msdn.microsoft.com/en-us/library/ms537512%28v=vs.85%29.aspx
165 // We do not care --\s>, which can possibly be intepreted as a valid close comment tag in very old browsers (e.g., firefox 3.6), as specified in the html4 spec
166 // Reference: http://www.w3.org/TR/html401/intro/sgmltut.html#h-3.2.4
167 yc: function (s) {
168 return typeof s === STR_UD ? STR_UD
169 : s === null ? STR_NL
170 : s.toString()
171 .replace(COMMENT_SENSITIVE_CHARS, function(m){
172 if (m === '-->') { return '-- >'; }
173 if (m === '--!>') { return '--! >'; }
174 if (m === '--!') { return '--! '; }
175 if (m === '--') { return '-- '; }
176 if (m === '-') { return '- '; }
177 if (m === ']>') { return '] >'; }
178 /*if (m === ']')*/ return '] ';
179 });
180 },
181
182 // FOR DETAILS, refer to inDoubleQuotedAttr()
183 // Reference: https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(double-quoted)-state
184 yavd: function (s) {
185 return typeof s === STR_UD ? STR_UD
186 : s === null ? STR_NL
187 : s.toString()
188 .replace(QUOT, '&quot;');
189 },
190
191 // FOR DETAILS, refer to inSingleQuotedAttr()
192 // Reference: https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(single-quoted)-state
193 yavs: function (s) {
194 return typeof s === STR_UD ? STR_UD
195 : s === null ? STR_NL
196 : s.toString()
197 .replace(SQUOT, '&#39;');
198 },
199
200 // FOR DETAILS, refer to inUnQuotedAttr()
201 // Reference: https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(unquoted)-state
202 // Reference: https://html.spec.whatwg.org/multipage/syntax.html#before-attribute-value-state
203 yavu: function (s) {
204 if (typeof s === STR_UD) { return STR_UD; }
205 if (s === null) { return STR_NL; }
206
207 s = s.toString().replace(ATTR_VALUE_UNQUOTED_CHARS, function (m) {
208 if (m === '\t') { return '&#9;'; } // in hex: 09
209 if (m === '\n') { return '&#10;'; } // in hex: 0A
210 if (m === '\f') { return '&#12;'; } // in hex: 0C
211 if (m === ' ') { return '&#32;'; } // in hex: 20
212 /*if (m === '>')*/ return '&gt;';
213 });
214
215 // if s starts with ' or ", encode it resp. as &#39; or &quot; to enforce the attr value (unquoted) state
216 // if instead starts with some whitespaces [\t\n\f ] then optionally a quote,
217 // then the above encoding has already enforced the attr value (unquoted) state
218 // therefore, no need to encode the quote
219 // Reference: https://html.spec.whatwg.org/multipage/syntax.html#before-attribute-value-state
220 s = s.replace(BEFORE_ATTR_VALUE_CHARS, function (m) {
221 if (m === '"') { return '&quot;'; }
222 if (m === "'") { return '&#39;'; }
223 /*if (m === '`')*/ return '&#96;'; // in hex: 60
224 });
225
226 // Inject NULL character if an empty string is encountered in
227 // unquoted attribute value state.
228 //
229 // Example:
230 // <input value={{yavu s}} name="passwd"/>
231 //
232 // Rationale 1: our belief is that developers wouldn't expect an
233 // empty string would result in ' name="firstname"' rendered as
234 // attribute value, even though this is how HTML5 is specified.
235 // Rationale 2: an empty string can effectively alter its immediate
236 // subsequent state, which violates our design principle. As per
237 // the HTML 5 spec, NULL or \u0000 is the magic character to end
238 // the comment state, which therefore will not mess up later
239 // contexts.
240 // Reference: https://html.spec.whatwg.org/multipage/syntax.html#before-attribute-value-state
241 return (s === '') ? '\u0000' : s;
242 },
243
244 yu: encodeURI,
245 yuc: encodeURIComponent,
246
247 /*
248 * =============================
249 * Rationale on data: protocol
250 * =============================
251 * Given there're two execution possibilities:
252 * 1. data:text/html,<script>alert(1)</script> in <(i)frame>'s src
253 * expected script execution but it's of a different origin than the included page. hence not CROSS-SITE scripting
254 * 2. data:application/javascript,alert(1) or data:,alert(1) in <script>'s src,
255 * data:text/css in <style>'s src
256 * data:image/svg+xml in <svg>'s src
257 * We already made it clear in the DISCLAIMER that anything involving <script>, <style>, and <svg> tags won't be taken care of
258 * Finally, we don't care the use of data: protocol
259 */
260 // Notice that yubl MUST BE APPLIED LAST, and will not be used independently (expected output from encodeURI/encodeURIComponent and yavd/yavs/yavu)
261 // This is used to disable JS execution capabilities by prefixing x- to ^javascript: or ^vbscript: that possibly could trigger script execution in URI attribute context
262 yubl: function (s) {
263
264 // assumption: s has gone through yavd/yavs/yavu(encodeURI/encodeURIComponent(s))
265 // chars like whitespaces are already turned to %-encoding
266 // so, let go if the first char is not &, j, J, v nor V
267 return (URI_SLOWLANE.indexOf(s[0]) === -1) ? s
268 : URI_BLACKLIST_REGEXP.test(s) ? 'x-' + s
269 : s;
270 },
271
272 // This is NOT a security-critical filter.
273 // Reference: https://tools.ietf.org/html/rfc3986
274 yufull: function (s) {
275 // return exports.yu(s)
276 return encodeURI(s)
277 .replace(URL_IPV6, function(m, p) {
278 return '//[' + p + ']';
279 });
280 }
281 };
282};
283
284// exposing privFilters
285// this is an undocumented feature, and please use it with extra care
286var privFilters = exports._privFilters = exports._getPrivFilters();
287
288
289/* chaining filters */
290
291// uriInAttr and literally uriPathInAttr
292// yubl is always used
293// Rationale: given pattern like this: <a href="{{{uriPathInDoubleQuotedAttr s}}}">
294// developer may expect s is always prefixed with ? or /, but an attacker can abuse it with 'javascript:alert(1)'
295function uriInAttr (s, yav, yu) {
296 return privFilters.yubl(yav((yu || privFilters.yufull)(s)));
297}
298
299/**
300* Yahoo Secure XSS Filters - just sufficient output filtering to prevent XSS!
301* @module xss-filters
302*/
303
304/**
305* @function module:xss-filters#inHTMLData
306*
307* @param {string} s - An untrusted user input
308* @returns {string} The string s with '<' encoded as '&amp;lt;'
309*
310* @description
311* This filter is to be placed in HTML Data context to encode all '<' characters into '&amp;lt;'
312* <ul>
313* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#data-state">HTML5 Data State</a></li>
314* </ul>
315*
316* @example
317* // output context to be applied by this filter.
318* <textarea>{{{inHTMLData html_data}}}</textarea>
319*
320*/
321exports.inHTMLData = privFilters.yd;
322
323
324/**
325* @function module:xss-filters#inHTMLComment
326*
327* @param {string} s - An untrusted user input
328* @returns {string} The string s with '-->', '--!>', ']>' respectively replaced with '-- >', '--! >', '] >'. In addition, a space is appended to those string s that ends with '-', '--', '--!', and ']'.
329*
330* @description
331* This filter is to be placed in HTML Comment context to disable any attempts in closing the html comment state
332* <p>Notice: --> and --!> are the syntaxes to close html comment state, while string that ends with -, --, or --! will also enable state closing if the variable is externally suffixed with -> or >.
333* ']>' and string that ends with ']' are changed to '] >' and '] ' to disable Internet Explorer conditional comments, which are actually not part of the HTML 5 standard.</p>
334*
335* <ul>
336* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#comment-state">HTML5 Comment State</a></li>
337* <li><a href="http://msdn.microsoft.com/en-us/library/ms537512%28v=vs.85%29.aspx">Conditional Comments in Internet Explorer</a></li>
338* </ul>
339*
340* @example
341* // output context to be applied by this filter.
342* <!-- {{{inHTMLComment html_comment}}} -->
343*
344*/
345exports.inHTMLComment = privFilters.yc;
346
347/**
348* @function module:xss-filters#inSingleQuotedAttr
349*
350* @param {string} s - An untrusted user input
351* @returns {string} The string s with any single-quote characters encoded into '&amp;&#39;'.
352*
353* @description
354* <p class="warning">Warning: This is NOT designed for any onX (e.g., onclick) attributes!</p>
355* <p class="warning">Warning: If you're working on URI/components, use the more specific uri___InSingleQuotedAttr filter </p>
356* This filter is to be placed in HTML Attribute Value (single-quoted) state to encode all single-quote characters into '&amp;&#39;'
357*
358* <ul>
359* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(single-quoted)-state">HTML5 Attribute Value (Single-Quoted) State</a></li>
360* </ul>
361*
362* @example
363* // output context to be applied by this filter.
364* <input name='firstname' value='{{{inSingleQuotedAttr firstname}}}' />
365*
366*/
367exports.inSingleQuotedAttr = privFilters.yavs;
368
369/**
370* @function module:xss-filters#inDoubleQuotedAttr
371*
372* @param {string} s - An untrusted user input
373* @returns {string} The string s with any single-quote characters encoded into '&amp;&quot;'.
374*
375* @description
376* <p class="warning">Warning: This is NOT designed for any onX (e.g., onclick) attributes!</p>
377* <p class="warning">Warning: If you're working on URI/components, use the more specific uri___InDoubleQuotedAttr filter </p>
378* This filter is to be placed in HTML Attribute Value (double-quoted) state to encode all single-quote characters into '&amp;&quot;'
379*
380* <ul>
381* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(double-quoted)-state">HTML5 Attribute Value (Double-Quoted) State</a></li>
382* </ul>
383*
384* @example
385* // output context to be applied by this filter.
386* <input name="firstname" value="{{{inDoubleQuotedAttr firstname}}}" />
387*
388*/
389exports.inDoubleQuotedAttr = privFilters.yavd;
390
391/**
392* @function module:xss-filters#inUnQuotedAttr
393*
394* @param {string} s - An untrusted user input
395* @returns {string} The string s with any tab, LF, FF, space, and '>' encoded. If the first char is either ' " or `, it is also encoded. If an empty string is encountered, return a NULL character '\u0000'.
396*
397* @description
398* <p class="warning">Warning: This is NOT designed for any onX (e.g., onclick) attributes!</p>
399* <p class="warning">Warning: If you're working on URI/components, use the more specific uri___InUnQuotedAttr filter </p>
400* This filter is to be placed in HTML Attribute Value (unquoted) state to encode tab, LF, FF, space, and '>' into their equivalent HTML entity representations.
401*
402* <ul>
403* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(unquoted)-state">HTML5 Attribute Value (Unquoted) State</a></li>
404* </ul>
405*
406* @example
407* // output context to be applied by this filter.
408* <input name="firstname" value={{{inUnQuotedAttr firstname}}} />
409*
410*/
411exports.inUnQuotedAttr = privFilters.yavu;
412
413
414/**
415* @function module:xss-filters#uriInSingleQuotedAttr
416*
417* @param {string} s - An untrusted user input, supposedly an <strong>absolute</strong> URI
418* @returns {string} The string s encoded first by window.encodeURI(), then inSingleQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
419*
420* @description
421* This filter is to be placed in HTML Attribute Value (single-quoted) state for an <strong>absolute</strong> URI.<br/>
422* The correct order of encoders is thus: first window.encodeURI(), then inSingleQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
423*
424* <p>Notice: This filter is IPv6 friendly by not encoding '[' and ']'.</p>
425*
426* <ul>
427* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI">encodeURI | MDN</a></li>
428* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
429* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(single-quoted)-state">HTML5 Attribute Value (Single-Quoted) State</a></li>
430* </ul>
431*
432* @example
433* // output context to be applied by this filter.
434* <a href='{{{uriInSingleQuotedAttr full_uri}}}'>link</a>
435*
436*/
437exports.uriInSingleQuotedAttr = function (s) {
438 return uriInAttr(s, privFilters.yavs);
439};
440
441/**
442* @function module:xss-filters#uriInDoubleQuotedAttr
443*
444* @param {string} s - An untrusted user input, supposedly an <strong>absolute</strong> URI
445* @returns {string} The string s encoded first by window.encodeURI(), then inDoubleQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
446*
447* @description
448* This filter is to be placed in HTML Attribute Value (double-quoted) state for an <strong>absolute</strong> URI.<br/>
449* The correct order of encoders is thus: first window.encodeURI(), then inDoubleQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
450*
451* <p>Notice: This filter is IPv6 friendly by not encoding '[' and ']'.</p>
452*
453* <ul>
454* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI">encodeURI | MDN</a></li>
455* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
456* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(double-quoted)-state">HTML5 Attribute Value (Double-Quoted) State</a></li>
457* </ul>
458*
459* @example
460* // output context to be applied by this filter.
461* <a href="{{{uriInDoubleQuotedAttr full_uri}}}">link</a>
462*
463*/
464exports.uriInDoubleQuotedAttr = function (s) {
465 return uriInAttr(s, privFilters.yavd);
466};
467
468
469/**
470* @function module:xss-filters#uriInUnQuotedAttr
471*
472* @param {string} s - An untrusted user input, supposedly an <strong>absolute</strong> URI
473* @returns {string} The string s encoded first by window.encodeURI(), then inUnQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
474*
475* @description
476* This filter is to be placed in HTML Attribute Value (unquoted) state for an <strong>absolute</strong> URI.<br/>
477* The correct order of encoders is thus: first the built-in encodeURI(), then inUnQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
478*
479* <p>Notice: This filter is IPv6 friendly by not encoding '[' and ']'.</p>
480*
481* <ul>
482* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI">encodeURI | MDN</a></li>
483* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
484* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(unquoted)-state">HTML5 Attribute Value (Unquoted) State</a></li>
485* </ul>
486*
487* @example
488* // output context to be applied by this filter.
489* <a href={{{uriInUnQuotedAttr full_uri}}}>link</a>
490*
491*/
492exports.uriInUnQuotedAttr = function (s) {
493 return uriInAttr(s, privFilters.yavu);
494};
495
496/**
497* @function module:xss-filters#uriInHTMLData
498*
499* @param {string} s - An untrusted user input, supposedly an <strong>absolute</strong> URI
500* @returns {string} The string s encoded by window.encodeURI() and then inHTMLData()
501*
502* @description
503* This filter is to be placed in HTML Data state for an <strong>absolute</strong> URI.
504*
505* <p>Notice: The actual implementation skips inHTMLData(), since '<' is already encoded as '%3C' by encodeURI().</p>
506* <p>Notice: This filter is IPv6 friendly by not encoding '[' and ']'.</p>
507*
508* <ul>
509* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI">encodeURI | MDN</a></li>
510* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
511* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#data-state">HTML5 Data State</a></li>
512* </ul>
513*
514* @example
515* // output context to be applied by this filter.
516* <a href="/somewhere">{{{uriInHTMLData full_uri}}}</a>
517*
518*/
519exports.uriInHTMLData = privFilters.yufull;
520
521
522/**
523* @function module:xss-filters#uriInHTMLComment
524*
525* @param {string} s - An untrusted user input, supposedly an <strong>absolute</strong> URI
526* @returns {string} The string s encoded by window.encodeURI(), and finally inHTMLComment()
527*
528* @description
529* This filter is to be placed in HTML Comment state for an <strong>absolute</strong> URI.
530*
531* <p>Notice: This filter is IPv6 friendly by not encoding '[' and ']'.</p>
532*
533* <ul>
534* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI">encodeURI | MDN</a></li>
535* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
536* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#data-state">HTML5 Data State</a></li>
537* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#comment-state">HTML5 Comment State</a></li>
538* </ul>
539*
540* @example
541* // output context to be applied by this filter.
542* <!-- {{{uriInHTMLComment full_uri}}} -->
543*
544*/
545exports.uriInHTMLComment = function (s) {
546 return privFilters.yc(privFilters.yufull(s));
547};
548
549
550
551
552/**
553* @function module:xss-filters#uriPathInSingleQuotedAttr
554*
555* @param {string} s - An untrusted user input, supposedly a URI Path/Query or relative URI
556* @returns {string} The string s encoded first by window.encodeURI(), then inSingleQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
557*
558* @description
559* This filter is to be placed in HTML Attribute Value (single-quoted) state for a URI Path/Query or relative URI.<br/>
560* The correct order of encoders is thus: first window.encodeURI(), then inSingleQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
561*
562* <ul>
563* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI">encodeURI | MDN</a></li>
564* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
565* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(single-quoted)-state">HTML5 Attribute Value (Single-Quoted) State</a></li>
566* </ul>
567*
568* @example
569* // output context to be applied by this filter.
570* <a href='http://example.com/{{{uriPathInSingleQuotedAttr uri_path}}}'>link</a>
571* <a href='http://example.com/?{{{uriQueryInSingleQuotedAttr uri_query}}}'>link</a>
572*
573*/
574exports.uriPathInSingleQuotedAttr = function (s) {
575 return uriInAttr(s, privFilters.yavs, privFilters.yu);
576};
577
578/**
579* @function module:xss-filters#uriPathInDoubleQuotedAttr
580*
581* @param {string} s - An untrusted user input, supposedly a URI Path/Query or relative URI
582* @returns {string} The string s encoded first by window.encodeURI(), then inDoubleQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
583*
584* @description
585* This filter is to be placed in HTML Attribute Value (double-quoted) state for a URI Path/Query or relative URI.<br/>
586* The correct order of encoders is thus: first window.encodeURI(), then inDoubleQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
587*
588* <ul>
589* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI">encodeURI | MDN</a></li>
590* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
591* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(double-quoted)-state">HTML5 Attribute Value (Double-Quoted) State</a></li>
592* </ul>
593*
594* @example
595* // output context to be applied by this filter.
596* <a href="http://example.com/{{{uriPathInDoubleQuotedAttr uri_path}}}">link</a>
597* <a href="http://example.com/?{{{uriQueryInDoubleQuotedAttr uri_query}}}">link</a>
598*
599*/
600exports.uriPathInDoubleQuotedAttr = function (s) {
601 return uriInAttr(s, privFilters.yavd, privFilters.yu);
602};
603
604
605/**
606* @function module:xss-filters#uriPathInUnQuotedAttr
607*
608* @param {string} s - An untrusted user input, supposedly a URI Path/Query or relative URI
609* @returns {string} The string s encoded first by window.encodeURI(), then inUnQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
610*
611* @description
612* This filter is to be placed in HTML Attribute Value (unquoted) state for a URI Path/Query or relative URI.<br/>
613* The correct order of encoders is thus: first the built-in encodeURI(), then inUnQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
614*
615* <ul>
616* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI">encodeURI | MDN</a></li>
617* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
618* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(unquoted)-state">HTML5 Attribute Value (Unquoted) State</a></li>
619* </ul>
620*
621* @example
622* // output context to be applied by this filter.
623* <a href=http://example.com/{{{uriPathInUnQuotedAttr uri_path}}}>link</a>
624* <a href=http://example.com/?{{{uriQueryInUnQuotedAttr uri_query}}}>link</a>
625*
626*/
627exports.uriPathInUnQuotedAttr = function (s) {
628 return uriInAttr(s, privFilters.yavu, privFilters.yu);
629};
630
631/**
632* @function module:xss-filters#uriPathInHTMLData
633*
634* @param {string} s - An untrusted user input, supposedly a URI Path/Query or relative URI
635* @returns {string} The string s encoded by window.encodeURI() and then inHTMLData()
636*
637* @description
638* This filter is to be placed in HTML Data state for a URI Path/Query or relative URI.
639*
640* <p>Notice: The actual implementation skips inHTMLData(), since '<' is already encoded as '%3C' by encodeURI().</p>
641*
642* <ul>
643* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI">encodeURI | MDN</a></li>
644* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
645* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#data-state">HTML5 Data State</a></li>
646* </ul>
647*
648* @example
649* // output context to be applied by this filter.
650* <a href="http://example.com/">http://example.com/{{{uriPathInHTMLData uri_path}}}</a>
651* <a href="http://example.com/">http://example.com/?{{{uriQueryInHTMLData uri_query}}}</a>
652*
653*/
654exports.uriPathInHTMLData = privFilters.yu;
655
656
657/**
658* @function module:xss-filters#uriPathInHTMLComment
659*
660* @param {string} s - An untrusted user input, supposedly a URI Path/Query or relative URI
661* @returns {string} The string s encoded by window.encodeURI(), and finally inHTMLComment()
662*
663* @description
664* This filter is to be placed in HTML Comment state for a URI Path/Query or relative URI.
665*
666* <ul>
667* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI">encodeURI | MDN</a></li>
668* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
669* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#data-state">HTML5 Data State</a></li>
670* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#comment-state">HTML5 Comment State</a></li>
671* </ul>
672*
673* @example
674* // output context to be applied by this filter.
675* <!-- http://example.com/{{{uriPathInHTMLComment uri_path}}} -->
676* <!-- http://example.com/?{{{uriQueryInHTMLComment uri_query}}} -->
677*/
678exports.uriPathInHTMLComment = function (s) {
679 return privFilters.yc(privFilters.yu(s));
680};
681
682
683/**
684* @function module:xss-filters#uriQueryInSingleQuotedAttr
685* @description This is an alias of {@link module:xss-filters#uriPathInSingleQuotedAttr}
686*
687* @alias module:xss-filters#uriPathInSingleQuotedAttr
688*/
689exports.uriQueryInSingleQuotedAttr = exports.uriPathInSingleQuotedAttr;
690
691/**
692* @function module:xss-filters#uriQueryInDoubleQuotedAttr
693* @description This is an alias of {@link module:xss-filters#uriPathInDoubleQuotedAttr}
694*
695* @alias module:xss-filters#uriPathInDoubleQuotedAttr
696*/
697exports.uriQueryInDoubleQuotedAttr = exports.uriPathInDoubleQuotedAttr;
698
699/**
700* @function module:xss-filters#uriQueryInUnQuotedAttr
701* @description This is an alias of {@link module:xss-filters#uriPathInUnQuotedAttr}
702*
703* @alias module:xss-filters#uriPathInUnQuotedAttr
704*/
705exports.uriQueryInUnQuotedAttr = exports.uriPathInUnQuotedAttr;
706
707/**
708* @function module:xss-filters#uriQueryInHTMLData
709* @description This is an alias of {@link module:xss-filters#uriPathInHTMLData}
710*
711* @alias module:xss-filters#uriPathInHTMLData
712*/
713exports.uriQueryInHTMLData = exports.uriPathInHTMLData;
714
715/**
716* @function module:xss-filters#uriQueryInHTMLComment
717* @description This is an alias of {@link module:xss-filters#uriPathInHTMLComment}
718*
719* @alias module:xss-filters#uriPathInHTMLComment
720*/
721exports.uriQueryInHTMLComment = exports.uriPathInHTMLComment;
722
723
724
725/**
726* @function module:xss-filters#uriComponentInSingleQuotedAttr
727*
728* @param {string} s - An untrusted user input, supposedly a URI Component
729* @returns {string} The string s encoded first by window.encodeURIComponent(), then inSingleQuotedAttr()
730*
731* @description
732* This filter is to be placed in HTML Attribute Value (single-quoted) state for a URI Component.<br/>
733* The correct order of encoders is thus: first window.encodeURIComponent(), then inSingleQuotedAttr()
734*
735*
736* <ul>
737* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent">encodeURIComponent | MDN</a></li>
738* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
739* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(single-quoted)-state">HTML5 Attribute Value (Single-Quoted) State</a></li>
740* </ul>
741*
742* @example
743* // output context to be applied by this filter.
744* <a href='http://example.com/?q={{{uriComponentInSingleQuotedAttr uri_component}}}'>link</a>
745*
746*/
747exports.uriComponentInSingleQuotedAttr = function (s) {
748 return privFilters.yavs(privFilters.yuc(s));
749};
750
751/**
752* @function module:xss-filters#uriComponentInDoubleQuotedAttr
753*
754* @param {string} s - An untrusted user input, supposedly a URI Component
755* @returns {string} The string s encoded first by window.encodeURIComponent(), then inDoubleQuotedAttr()
756*
757* @description
758* This filter is to be placed in HTML Attribute Value (double-quoted) state for a URI Component.<br/>
759* The correct order of encoders is thus: first window.encodeURIComponent(), then inDoubleQuotedAttr()
760*
761*
762* <ul>
763* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent">encodeURIComponent | MDN</a></li>
764* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
765* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(double-quoted)-state">HTML5 Attribute Value (Double-Quoted) State</a></li>
766* </ul>
767*
768* @example
769* // output context to be applied by this filter.
770* <a href="http://example.com/?q={{{uriComponentInDoubleQuotedAttr uri_component}}}">link</a>
771*
772*/
773exports.uriComponentInDoubleQuotedAttr = function (s) {
774 return privFilters.yavd(privFilters.yuc(s));
775};
776
777
778/**
779* @function module:xss-filters#uriComponentInUnQuotedAttr
780*
781* @param {string} s - An untrusted user input, supposedly a URI Component
782* @returns {string} The string s encoded first by window.encodeURIComponent(), then inUnQuotedAttr()
783*
784* @description
785* This filter is to be placed in HTML Attribute Value (unquoted) state for a URI Component.<br/>
786* The correct order of encoders is thus: first the built-in encodeURIComponent(), then inUnQuotedAttr()
787*
788*
789* <ul>
790* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent">encodeURIComponent | MDN</a></li>
791* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
792* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(unquoted)-state">HTML5 Attribute Value (Unquoted) State</a></li>
793* </ul>
794*
795* @example
796* // output context to be applied by this filter.
797* <a href=http://example.com/?q={{{uriComponentInUnQuotedAttr uri_component}}}>link</a>
798*
799*/
800exports.uriComponentInUnQuotedAttr = function (s) {
801 return privFilters.yavu(privFilters.yuc(s));
802};
803
804/**
805* @function module:xss-filters#uriComponentInHTMLData
806*
807* @param {string} s - An untrusted user input, supposedly a URI Component
808* @returns {string} The string s encoded by window.encodeURIComponent() and then inHTMLData()
809*
810* @description
811* This filter is to be placed in HTML Data state for a URI Component.
812*
813* <p>Notice: The actual implementation skips inHTMLData(), since '<' is already encoded as '%3C' by encodeURIComponent().</p>
814*
815* <ul>
816* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent">encodeURIComponent | MDN</a></li>
817* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
818* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#data-state">HTML5 Data State</a></li>
819* </ul>
820*
821* @example
822* // output context to be applied by this filter.
823* <a href="http://example.com/">http://example.com/?q={{{uriComponentInHTMLData uri_component}}}</a>
824* <a href="http://example.com/">http://example.com/#{{{uriComponentInHTMLData uri_fragment}}}</a>
825*
826*/
827exports.uriComponentInHTMLData = privFilters.yuc;
828
829
830/**
831* @function module:xss-filters#uriComponentInHTMLComment
832*
833* @param {string} s - An untrusted user input, supposedly a URI Component
834* @returns {string} The string s encoded by window.encodeURIComponent(), and finally inHTMLComment()
835*
836* @description
837* This filter is to be placed in HTML Comment state for a URI Component.
838*
839* <ul>
840* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent">encodeURIComponent | MDN</a></li>
841* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
842* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#data-state">HTML5 Data State</a></li>
843* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#comment-state">HTML5 Comment State</a></li>
844* </ul>
845*
846* @example
847* // output context to be applied by this filter.
848* <!-- http://example.com/?q={{{uriComponentInHTMLComment uri_component}}} -->
849* <!-- http://example.com/#{{{uriComponentInHTMLComment uri_fragment}}} -->
850*/
851exports.uriComponentInHTMLComment = function (s) {
852 return privFilters.yc(privFilters.yuc(s));
853};
854
855
856// uriFragmentInSingleQuotedAttr
857// added yubl on top of uriComponentInAttr
858// Rationale: given pattern like this: <a href='{{{uriFragmentInSingleQuotedAttr s}}}'>
859// developer may expect s is always prefixed with #, but an attacker can abuse it with 'javascript:alert(1)'
860
861/**
862* @function module:xss-filters#uriFragmentInSingleQuotedAttr
863*
864* @param {string} s - An untrusted user input, supposedly a URI Fragment
865* @returns {string} The string s encoded first by window.encodeURIComponent(), then inSingleQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
866*
867* @description
868* This filter is to be placed in HTML Attribute Value (single-quoted) state for a URI Fragment.<br/>
869* The correct order of encoders is thus: first window.encodeURIComponent(), then inSingleQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
870*
871*
872* <ul>
873* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent">encodeURIComponent | MDN</a></li>
874* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
875* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(single-quoted)-state">HTML5 Attribute Value (Single-Quoted) State</a></li>
876* </ul>
877*
878* @example
879* // output context to be applied by this filter.
880* <a href='http://example.com/#{{{uriFragmentInSingleQuotedAttr uri_fragment}}}'>link</a>
881*
882*/
883exports.uriFragmentInSingleQuotedAttr = function (s) {
884 return privFilters.yubl(privFilters.yavs(privFilters.yuc(s)));
885};
886
887// uriFragmentInDoubleQuotedAttr
888// added yubl on top of uriComponentInAttr
889// Rationale: given pattern like this: <a href="{{{uriFragmentInDoubleQuotedAttr s}}}">
890// developer may expect s is always prefixed with #, but an attacker can abuse it with 'javascript:alert(1)'
891
892/**
893* @function module:xss-filters#uriFragmentInDoubleQuotedAttr
894*
895* @param {string} s - An untrusted user input, supposedly a URI Fragment
896* @returns {string} The string s encoded first by window.encodeURIComponent(), then inDoubleQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
897*
898* @description
899* This filter is to be placed in HTML Attribute Value (double-quoted) state for a URI Fragment.<br/>
900* The correct order of encoders is thus: first window.encodeURIComponent(), then inDoubleQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
901*
902*
903* <ul>
904* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent">encodeURIComponent | MDN</a></li>
905* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
906* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(double-quoted)-state">HTML5 Attribute Value (Double-Quoted) State</a></li>
907* </ul>
908*
909* @example
910* // output context to be applied by this filter.
911* <a href="http://example.com/#{{{uriFragmentInDoubleQuotedAttr uri_fragment}}}">link</a>
912*
913*/
914exports.uriFragmentInDoubleQuotedAttr = function (s) {
915 return privFilters.yubl(privFilters.yavd(privFilters.yuc(s)));
916};
917
918// uriFragmentInUnQuotedAttr
919// added yubl on top of uriComponentInAttr
920// Rationale: given pattern like this: <a href={{{uriFragmentInUnQuotedAttr s}}}>
921// developer may expect s is always prefixed with #, but an attacker can abuse it with 'javascript:alert(1)'
922
923/**
924* @function module:xss-filters#uriFragmentInUnQuotedAttr
925*
926* @param {string} s - An untrusted user input, supposedly a URI Fragment
927* @returns {string} The string s encoded first by window.encodeURIComponent(), then inUnQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
928*
929* @description
930* This filter is to be placed in HTML Attribute Value (unquoted) state for a URI Fragment.<br/>
931* The correct order of encoders is thus: first the built-in encodeURIComponent(), then inUnQuotedAttr(), and finally prefix the resulted string with 'x-' if it begins with 'javascript:' or 'vbscript:' that could possibly lead to script execution
932*
933* <ul>
934* <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent">encodeURIComponent | MDN</a></li>
935* <li><a href="http://tools.ietf.org/html/rfc3986">RFC 3986</a></li>
936* <li><a href="https://html.spec.whatwg.org/multipage/syntax.html#attribute-value-(unquoted)-state">HTML5 Attribute Value (Unquoted) State</a></li>
937* </ul>
938*
939* @example
940* // output context to be applied by this filter.
941* <a href=http://example.com/#{{{uriFragmentInUnQuotedAttr uri_fragment}}}>link</a>
942*
943*/
944exports.uriFragmentInUnQuotedAttr = function (s) {
945 return privFilters.yubl(privFilters.yavu(privFilters.yuc(s)));
946};
947
948
949/**
950* @function module:xss-filters#uriFragmentInHTMLData
951* @description This is an alias of {@link module:xss-filters#uriComponentInHTMLData}
952*
953* @alias module:xss-filters#uriComponentInHTMLData
954*/
955exports.uriFragmentInHTMLData = exports.uriComponentInHTMLData;
956
957/**
958* @function module:xss-filters#uriFragmentInHTMLComment
959* @description This is an alias of {@link module:xss-filters#uriComponentInHTMLComment}
960*
961* @alias module:xss-filters#uriComponentInHTMLComment
962*/
963exports.uriFragmentInHTMLComment = exports.uriComponentInHTMLComment;