dompurify 2.0.13 → 2.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG.
8
8
 
9
- It's also very simple to use and get started with. DOMPurify was [started in February 2014](https://github.com/cure53/DOMPurify/commit/a630922616927373485e0e787ab19e73e3691b2b) and, meanwhile, has reached version 2.0.13.
9
+ It's also very simple to use and get started with. DOMPurify was [started in February 2014](https://github.com/cure53/DOMPurify/commit/a630922616927373485e0e787ab19e73e3691b2b) and, meanwhile, has reached version 2.0.17.
10
10
 
11
11
  DOMPurify is written in JavaScript and works in all modern browsers (Safari, Opera (15+), Internet Explorer (10+), Edge, Firefox and Chrome - as well as almost anything else using Blink or WebKit). It doesn't break on MSIE6 or other legacy browsers. It either uses [a fall-back](#what-about-older-browsers-like-msie8) or simply does nothing.
12
12
 
@@ -137,6 +137,9 @@ When `DOMPurify.sanitize` is used in an environment where the Trusted Types API
137
137
  Yes. The included default configuration values are pretty good already - but you can of course override them. Check out the [`/demos`](https://github.com/cure53/DOMPurify/tree/main/demos) folder to see a bunch of examples on how you can [customize DOMPurify](https://github.com/cure53/DOMPurify/tree/main/demos#what-is-this).
138
138
 
139
139
  ```js
140
+ /**
141
+ * General settings
142
+ */
140
143
  // make output safe for usage in jQuery's $()/html() method (default is false)
141
144
  var clean = DOMPurify.sanitize(dirty, {SAFE_FOR_JQUERY: true});
142
145
 
@@ -146,48 +149,63 @@ var clean = DOMPurify.sanitize(dirty, {SAFE_FOR_JQUERY: true});
146
149
  // only use this mode if there is really no alternative.
147
150
  var clean = DOMPurify.sanitize(dirty, {SAFE_FOR_TEMPLATES: true});
148
151
 
149
- // allow only <b>
152
+ /**
153
+ * Control our allow-lists and block-lists
154
+ */
155
+ // allow only <b> elements, very strict
150
156
  var clean = DOMPurify.sanitize(dirty, {ALLOWED_TAGS: ['b']});
151
157
 
152
- // allow only <b> and <q> with style attributes (for whatever reason)
158
+ // allow only <b> and <q> with style attributes
153
159
  var clean = DOMPurify.sanitize(dirty, {ALLOWED_TAGS: ['b', 'q'], ALLOWED_ATTR: ['style']});
154
160
 
155
161
  // allow all safe HTML elements but neither SVG nor MathML
156
162
  var clean = DOMPurify.sanitize(dirty, {USE_PROFILES: {html: true}});
157
163
 
158
- // allow all safe SVG elements and SVG Filters
164
+ // allow all safe SVG elements and SVG Filters, no HTML or MathML
159
165
  var clean = DOMPurify.sanitize(dirty, {USE_PROFILES: {svg: true, svgFilters: true}});
160
166
 
161
- // allow all safe MathML elements and SVG
167
+ // allow all safe MathML elements and SVG, but no SVG Filters
162
168
  var clean = DOMPurify.sanitize(dirty, {USE_PROFILES: {mathMl: true, svg: true}});
163
169
 
164
- // leave all as it is but forbid <style>
170
+ // leave all safe HTML as it is and add <style> elements to block-list
165
171
  var clean = DOMPurify.sanitize(dirty, {FORBID_TAGS: ['style']});
166
172
 
167
- // leave all as it is but forbid style attributes
173
+ // leave all safe HTML as it is and add style attributes to block-list
168
174
  var clean = DOMPurify.sanitize(dirty, {FORBID_ATTR: ['style']});
169
175
 
170
- // extend the existing array of allowed tags
176
+ // extend the existing array of allowed tags and add <my-tag> to allow-list
171
177
  var clean = DOMPurify.sanitize(dirty, {ADD_TAGS: ['my-tag']});
172
178
 
173
- // extend the existing array of attributes
179
+ // extend the existing array of allowed attributes and add my-attr to allow-list
174
180
  var clean = DOMPurify.sanitize(dirty, {ADD_ATTR: ['my-attr']});
175
181
 
176
- // extend the existing array of tags that can use Data URIs
182
+ // prohibit HTML5 data attributes, leave other safe HTML as is (default is true)
183
+ var clean = DOMPurify.sanitize(dirty, {ALLOW_DATA_ATTR: false});
184
+
185
+ /**
186
+ * Control behavior relating to URI values
187
+ */
188
+ // extend the existing array of elements that can use Data URIs
177
189
  var clean = DOMPurify.sanitize(dirty, {ADD_DATA_URI_TAGS: ['a', 'area']});
178
190
 
179
- // prohibit HTML5 data attributes (default is true)
180
- var clean = DOMPurify.sanitize(dirty, {ALLOW_DATA_ATTR: false});
191
+ // extend the existing array of elements that are safe for URI-like values (be careful, XSS risk)
192
+ var clean = DOMPurify.sanitize(dirty, {ADD_URI_SAFE_ATTR: ['my-attr']});
181
193
 
182
- // allow external protocol handlers in URL attributes (default is false)
194
+ /**
195
+ * Control permitted attribute values
196
+ */
197
+ // allow external protocol handlers in URL attributes (default is false, be careful, XSS risk)
183
198
  // by default only http, https, ftp, ftps, tel, mailto, callto, cid and xmpp are allowed.
184
199
  var clean = DOMPurify.sanitize(dirty, {ALLOW_UNKNOWN_PROTOCOLS: true});
185
200
 
186
- // allow specific protocols handlers in URL attributes (default is false)
201
+ // allow specific protocols handlers in URL attributes via regex (default is false, be careful, XSS risk)
187
202
  // by default only http, https, ftp, ftps, tel, mailto, callto, cid and xmpp are allowed.
188
203
  // Default RegExp: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i;
189
204
  var clean = DOMPurify.sanitize(dirty, {ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp|xxx):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i;});
190
205
 
206
+ /**
207
+ * Influence the return-type
208
+ */
191
209
  // return a DOM HTMLBodyElement instead of an HTML string (default is false)
192
210
  var clean = DOMPurify.sanitize(dirty, {RETURN_DOM: true});
193
211
 
@@ -204,18 +222,24 @@ document.body.appendChild(clean);
204
222
  // use the RETURN_TRUSTED_TYPE flag to turn on Trusted Types support if available
205
223
  var clean = DOMPurify.sanitize(dirty, {RETURN_TRUSTED_TYPE: true}); // will return a TrustedHTML object instead of a string if possible
206
224
 
225
+ /**
226
+ * Influence how we sanitize
227
+ */
207
228
  // return entire document including <html> tags (default is false)
208
229
  var clean = DOMPurify.sanitize(dirty, {WHOLE_DOCUMENT: true});
209
230
 
210
- // disable DOM Clobbering protection on output (default is true, handle with care!)
231
+ // disable DOM Clobbering protection on output (default is true, handle with care, minor XSS risks here)
211
232
  var clean = DOMPurify.sanitize(dirty, {SANITIZE_DOM: false});
212
233
 
213
- // keep an element's content when the element is removed (default is true)
234
+ // keep an element's content when the element is removed (default is true, careful, minor XSS risks here)
214
235
  var clean = DOMPurify.sanitize(dirty, {KEEP_CONTENT: false});
215
236
 
216
237
  // glue elements like style, script or others to document.body and prevent unintuitive browser behavior in several edge-cases (default is false)
217
238
  var clean = DOMPurify.sanitize(dirty, {FORCE_BODY: true});
218
239
 
240
+ /**
241
+ * Influence where we sanitize
242
+ */
219
243
  // use the IN_PLACE mode to sanitize a node "in place", which is much faster depending on how you use DOMPurify
220
244
  var dirty = document.createElement('a');
221
245
  dirty.setAttribute('href', 'javascript:alert(1)');
@@ -304,7 +328,7 @@ Feature releases will not be announced to this list.
304
328
 
305
329
  Many people helped and help DOMPurify become what it is and need to be acknowledged here!
306
330
 
307
- [oreoshake 💸](https://github.com/oreoshake), [dcramer 💸](https://github.com/dcramer),[tdeekens ❤️](https://github.com/tdeekens), [neilj](https://github.com/neilj), [fhemberger](https://github.com/fhemberger), [Joris-van-der-Wel](https://github.com/Joris-van-der-Wel), [ydaniv](https://github.com/ydaniv), [filedescriptor](https://github.com/filedescriptor), [ConradIrwin](https://github.com/ConradIrwin), [gibson042](https://github.com/gibson042), [choumx](https://github.com/choumx), [0xSobky](https://github.com/0xSobky), [styfle](https://github.com/styfle), [koto](https://github.com/koto), [tlau88](https://github.com/tlau88), [strugee](https://github.com/strugee), [oparoz](https://github.com/oparoz), [mathiasbynens](https://github.com/mathiasbynens), [edg2s](https://github.com/edg2s), [dnkolegov](https://github.com/dnkolegov), [dhardtke](https://github.com/dhardtke), [wirehead](https://github.com/wirehead), [thorn0](https://github.com/thorn0), [styu](https://github.com/styu), [mozfreddyb](https://github.com/mozfreddyb), [mikesamuel](https://github.com/mikesamuel), [jorangreef](https://github.com/jorangreef), [jimmyhchan](https://github.com/jimmyhchan), [jameydeorio](https://github.com/jameydeorio), [jameskraus](https://github.com/jameskraus), [hyderali](https://github.com/hyderali), [hansottowirtz](https://github.com/hansottowirtz), [hackvertor](https://github.com/hackvertor), [freddyb](https://github.com/freddyb), [flavorjones](https://github.com/flavorjones), [djfarrelly](https://github.com/djfarrelly), [devd](https://github.com/devd), [camerondunford](https://github.com/camerondunford), [buu700](https://github.com/buu700), [buildog](https://github.com/buildog), [alabiaga](https://github.com/alabiaga), [Vector919](https://github.com/Vector919), [Robbert](https://github.com/Robbert), [GreLI](https://github.com/GreLI), [FuzzySockets](https://github.com/FuzzySockets), [ArtemBernatskyy](https://github.com/ArtemBernatskyy), [@garethheyes](https://twitter.com/garethheyes), [@filedescriptor](https://twitter.com/filedescriptor), [@shafigullin](https://twitter.com/shafigullin), [@mmrupp](https://twitter.com/mmrupp), [@irsdl](https://twitter.com/irsdl),[ShikariSenpai](https://github.com/ShikariSenpai), [ansjdnakjdnajkd](https://github.com/ansjdnakjdnajkd), [@asutherland](https://twitter.com/asutherland), [@mathias](https://twitter.com/mathias), [@cgvwzq](https://twitter.com/cgvwzq), [@robbertatwork](https://twitter.com/robbertatwork), [@giutro](https://twitter.com/giutro) and especially [@masatokinugawa](https://twitter.com/masatokinugawa)
331
+ [oreoshake 💸](https://github.com/oreoshake), [dcramer 💸](https://github.com/dcramer),[tdeekens ❤️](https://github.com/tdeekens), [peernohell ❤️](https://github.com/peernohell), [neilj](https://github.com/neilj), [fhemberger](https://github.com/fhemberger), [Joris-van-der-Wel](https://github.com/Joris-van-der-Wel), [ydaniv](https://github.com/ydaniv), [filedescriptor](https://github.com/filedescriptor), [ConradIrwin](https://github.com/ConradIrwin), [gibson042](https://github.com/gibson042), [choumx](https://github.com/choumx), [0xSobky](https://github.com/0xSobky), [styfle](https://github.com/styfle), [koto](https://github.com/koto), [tlau88](https://github.com/tlau88), [strugee](https://github.com/strugee), [oparoz](https://github.com/oparoz), [mathiasbynens](https://github.com/mathiasbynens), [edg2s](https://github.com/edg2s), [dnkolegov](https://github.com/dnkolegov), [dhardtke](https://github.com/dhardtke), [wirehead](https://github.com/wirehead), [thorn0](https://github.com/thorn0), [styu](https://github.com/styu), [mozfreddyb](https://github.com/mozfreddyb), [mikesamuel](https://github.com/mikesamuel), [jorangreef](https://github.com/jorangreef), [jimmyhchan](https://github.com/jimmyhchan), [jameydeorio](https://github.com/jameydeorio), [jameskraus](https://github.com/jameskraus), [hyderali](https://github.com/hyderali), [hansottowirtz](https://github.com/hansottowirtz), [hackvertor](https://github.com/hackvertor), [freddyb](https://github.com/freddyb), [flavorjones](https://github.com/flavorjones), [djfarrelly](https://github.com/djfarrelly), [devd](https://github.com/devd), [camerondunford](https://github.com/camerondunford), [buu700](https://github.com/buu700), [buildog](https://github.com/buildog), [alabiaga](https://github.com/alabiaga), [Vector919](https://github.com/Vector919), [Robbert](https://github.com/Robbert), [GreLI](https://github.com/GreLI), [FuzzySockets](https://github.com/FuzzySockets), [ArtemBernatskyy](https://github.com/ArtemBernatskyy), [@garethheyes](https://twitter.com/garethheyes), [@filedescriptor](https://twitter.com/filedescriptor), [@shafigullin](https://twitter.com/shafigullin), [@mmrupp](https://twitter.com/mmrupp), [@irsdl](https://twitter.com/irsdl),[ShikariSenpai](https://github.com/ShikariSenpai), [ansjdnakjdnajkd](https://github.com/ansjdnakjdnajkd), [@asutherland](https://twitter.com/asutherland), [@mathias](https://twitter.com/mathias), [@cgvwzq](https://twitter.com/cgvwzq), [@robbertatwork](https://twitter.com/robbertatwork), [@giutro](https://twitter.com/giutro) and especially [@masatokinugawa](https://twitter.com/masatokinugawa)
308
332
 
309
333
  ## Testing powered by
310
334
  <a target="_blank" href="https://www.browserstack.com/"><img width="200" src="https://www.browserstack.com/images/layout/browserstack-logo-600x315.png"></a><br>
@@ -149,7 +149,7 @@ var ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
149
149
  var IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
150
150
  );
151
151
  var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
152
- var ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205f\u3000]/g // eslint-disable-line no-control-regex
152
+ var ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
153
153
  );
154
154
 
155
155
  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
@@ -210,7 +210,7 @@ function createDOMPurify() {
210
210
  * Version label, exposed for easier checks
211
211
  * if DOMPurify is up to date or not
212
212
  */
213
- DOMPurify.version = '2.0.13';
213
+ DOMPurify.version = '2.0.17';
214
214
 
215
215
  /**
216
216
  * Array of elements that DOMPurify removed during sanitation.
@@ -266,7 +266,10 @@ function createDOMPurify() {
266
266
  var importNode = originalDocument.importNode;
267
267
 
268
268
 
269
- var documentMode = clone(document).documentMode ? document.documentMode : null;
269
+ var documentMode = {};
270
+ try {
271
+ documentMode = clone(document).documentMode ? document.documentMode : {};
272
+ } catch (_) {}
270
273
 
271
274
  var hooks = {};
272
275
 
@@ -346,7 +349,7 @@ function createDOMPurify() {
346
349
  * DOMPurify. */
347
350
  var RETURN_DOM_IMPORT = false;
348
351
 
349
- /* Try to return a Trusted Type object instead of a string, retrun a string in
352
+ /* Try to return a Trusted Type object instead of a string, return a string in
350
353
  * case Trusted Types are not supported */
351
354
  var RETURN_TRUSTED_TYPE = false;
352
355
 
@@ -514,7 +517,6 @@ function createDOMPurify() {
514
517
  var _forceRemove = function _forceRemove(node) {
515
518
  arrayPush(DOMPurify.removed, { element: node });
516
519
  try {
517
- // eslint-disable-next-line unicorn/prefer-node-remove
518
520
  node.parentNode.removeChild(node);
519
521
  } catch (_) {
520
522
  node.outerHTML = emptyHTML;
@@ -700,7 +702,7 @@ function createDOMPurify() {
700
702
  });
701
703
 
702
704
  /* Take care of an mXSS pattern using p, br inside svg, math */
703
- if ((tagName === 'svg' || tagName === 'math') && currentNode.querySelectorAll('p, br').length !== 0) {
705
+ if ((tagName === 'svg' || tagName === 'math') && currentNode.querySelectorAll('p, br, form, table').length !== 0) {
704
706
  _forceRemove(currentNode);
705
707
  return true;
706
708
  }
@@ -731,7 +733,7 @@ function createDOMPurify() {
731
733
  }
732
734
 
733
735
  /* Convert markup to cover jQuery behavior */
734
- if (SAFE_FOR_JQUERY && !currentNode.firstElementChild && (!currentNode.content || !currentNode.content.firstElementChild) && regExpTest(/</g, currentNode.textContent)) {
736
+ if (SAFE_FOR_JQUERY && !_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/</g, currentNode.textContent)) {
735
737
  arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });
736
738
  if (currentNode.innerHTML) {
737
739
  currentNode.innerHTML = stringReplace(currentNode.innerHTML, /</g, '&lt;');