dompurify 2.0.11 → 2.0.15

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
@@ -1,16 +1,16 @@
1
1
  # DOMPurify
2
2
 
3
- [![Bower version](https://badge.fury.io/bo/dompurify.svg)](http://badge.fury.io/bo/dompurify) · [![npm version](https://badge.fury.io/js/dompurify.svg)](http://badge.fury.io/js/dompurify) · ![Build and Test](https://github.com/cure53/DOMPurify/workflows/Build%20and%20Test/badge.svg?branch=master) · [![Downloads](https://img.shields.io/npm/dm/dompurify.svg)](https://www.npmjs.com/package/dompurify) · [![gzip size](http://img.badgesize.io/https://cdn.jsdelivr.net/npm/dompurify/dist/purify.min.js?compression=gzip)](https://cdn.jsdelivr.net/npm/dompurify/dist/purify.min.js) · [![install size](https://badgen.net/packagephobia/install/dompurify)](https://packagephobia.now.sh/result?p=dompurify)
3
+ [![npm version](https://badge.fury.io/js/dompurify.svg)](http://badge.fury.io/js/dompurify) ![Build and Test](https://github.com/cure53/DOMPurify/workflows/Build%20and%20Test/badge.svg?branch=main) [![Downloads](https://img.shields.io/npm/dm/dompurify.svg)](https://www.npmjs.com/package/dompurify) [![minified size](https://badgen.net/bundlephobia/min/dompurify?color=green&label=minified)](https://cdn.jsdelivr.net/npm/dompurify/dist/purify.min.js) [![gzip size](https://badgen.net/bundlephobia/minzip/dompurify?color=green&label=gzipped)](https://packagephobia.now.sh/result?p=dompurify) [![dependents](https://badgen.net/github/dependents-repo/cure53/dompurify?color=green&label=dependents)](https://github.com/cure53/DOMPurify/network/dependents)
4
4
 
5
5
  [![NPM](https://nodei.co/npm/dompurify.png)](https://nodei.co/npm/dompurify/)
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.11.
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.15.
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
 
13
- Our automated tests cover [26 different browsers](https://github.com/cure53/DOMPurify/blob/master/test/karma.custom-launchers.config.js#L5) right now, more to come. We also cover Node.js v12.0.0 and v13.0.0, running DOMPurify on [jsdom](https://github.com/tmpvar/jsdom). Older Node.js versions are known to work as well.
13
+ Our automated tests cover [26 different browsers](https://github.com/cure53/DOMPurify/blob/main/test/karma.custom-launchers.config.js#L5) right now, more to come. We also cover Node.js v12.0.0 and v13.0.0, running DOMPurify on [jsdom](https://github.com/tmpvar/jsdom). Older Node.js versions are known to work as well.
14
14
 
15
15
  DOMPurify is written by security people who have vast background in web attacks and XSS. Fear not. For more details please also read about our [Security Goals & Threat Model](https://github.com/cure53/DOMPurify/wiki/Security-Goals-&-Threat-Model). Please, read it. Like, really.
16
16
 
@@ -98,7 +98,7 @@ Of course there is a demo! [Play with DOMPurify](https://cure53.de/purify)
98
98
 
99
99
  First of all, please immediately contact us via [email](mailto:mario@cure53.de) so we can work on a fix. [PGP key](https://keyserver.ubuntu.com/pks/lookup?op=vindex&search=0xC26C858090F70ADA)
100
100
 
101
- Also, you probably qualify for a bug bounty! The fine folks over at [FastMail](https://www.fastmail.com/) use DOMPurify for their services and added our library to their bug bounty scope. So, if you find a way to bypass or weaken DOMPurify, please also have a look at their website and the [bug bounty info](https://www.fastmail.com/about/bugbounty.html).
101
+ Also, you probably qualify for a bug bounty! The fine folks over at [Fastmail](https://www.fastmail.com/) use DOMPurify for their services and added our library to their bug bounty scope. So, if you find a way to bypass or weaken DOMPurify, please also have a look at their website and the [bug bounty info](https://www.fastmail.com/about/bugbounty.html).
102
102
 
103
103
  ## Some purification samples please?
104
104
 
@@ -134,9 +134,12 @@ When `DOMPurify.sanitize` is used in an environment where the Trusted Types API
134
134
 
135
135
  ## Can I configure DOMPurify?
136
136
 
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/master/demos) folder to see a bunch of examples on how you can [customize DOMPurify](https://github.com/cure53/DOMPurify/tree/master/demos#what-is-this).
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,25 +222,31 @@ 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)');
222
246
  var clean = DOMPurify.sanitize(dirty, {IN_PLACE: true}); // see https://github.com/cure53/DOMPurify/issues/288 for more info
223
247
  ```
224
248
 
225
- There is even [more examples here](https://github.com/cure53/DOMPurify/tree/master/demos#what-is-this), showing how you can run, customize and configure DOMPurify to fit your needs.
249
+ There is even [more examples here](https://github.com/cure53/DOMPurify/tree/main/demos#what-is-this), showing how you can run, customize and configure DOMPurify to fit your needs.
226
250
 
227
251
  ## Persistent Configuration
228
252
 
@@ -242,7 +266,7 @@ DOMPurify allows you to augment its functionality by attaching one or more funct
242
266
  - `uponSanitizeShadowNode`
243
267
  - `afterSanitizeShadowDOM`
244
268
 
245
- It passes the currently processed DOM node, when needed a literal with verified node and attribute data and the DOMPurify configuration to the callback. Check out the [MentalJS hook demo](https://github.com/cure53/DOMPurify/blob/master/demos/hooks-mentaljs-demo.html) to see how the API can be used nicely.
269
+ It passes the currently processed DOM node, when needed a literal with verified node and attribute data and the DOMPurify configuration to the callback. Check out the [MentalJS hook demo](https://github.com/cure53/DOMPurify/blob/main/demos/hooks-mentaljs-demo.html) to see how the API can be used nicely.
246
270
 
247
271
  _Example_:
248
272
 
@@ -304,6 +328,9 @@ 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)
332
+
333
+ ## Testing powered by
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>
308
335
 
309
- And last but not least, thanks to [BrowserStack](https://browserstack.com) for supporting this project with their services for free and delivering excellent, dedicated and very professional support on top of that.
336
+ And last but not least, thanks to [BrowserStack Open-Source Program](https://www.browserstack.com/open-source) for supporting this project with their services for free and delivering excellent, dedicated and very professional support on top of that.
@@ -9,7 +9,8 @@ var hasOwnProperty = Object.hasOwnProperty,
9
9
  isFrozen = Object.isFrozen,
10
10
  objectKeys = Object.keys;
11
11
  var freeze = Object.freeze,
12
- seal = Object.seal; // eslint-disable-line import/no-mutable-exports
12
+ seal = Object.seal,
13
+ create = Object.create; // eslint-disable-line import/no-mutable-exports
13
14
 
14
15
  var _ref = typeof Reflect !== 'undefined' && Reflect,
15
16
  apply = _ref.apply,
@@ -109,7 +110,7 @@ function addToSet(set, array) {
109
110
 
110
111
  /* Shallow clone an object */
111
112
  function clone(object) {
112
- var newObject = {};
113
+ var newObject = create(null);
113
114
 
114
115
  var property = void 0;
115
116
  for (property in object) {
@@ -134,7 +135,7 @@ var text = freeze(['#text']);
134
135
 
135
136
  var html$1 = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'xmlns']);
136
137
 
137
- var svg$1 = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'tabindex', 'targetx', 'targety', 'transform', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
138
+ var svg$1 = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'targetx', 'targety', 'transform', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
138
139
 
139
140
  var mathMl$1 = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);
140
141
 
@@ -148,7 +149,7 @@ var ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
148
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
149
150
  );
150
151
  var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
151
- 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
152
153
  );
153
154
 
154
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; };
@@ -209,7 +210,7 @@ function createDOMPurify() {
209
210
  * Version label, exposed for easier checks
210
211
  * if DOMPurify is up to date or not
211
212
  */
212
- DOMPurify.version = '2.0.11';
213
+ DOMPurify.version = '2.0.15';
213
214
 
214
215
  /**
215
216
  * Array of elements that DOMPurify removed during sanitation.
@@ -255,7 +256,7 @@ function createDOMPurify() {
255
256
  }
256
257
 
257
258
  var trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, originalDocument);
258
- var emptyHTML = trustedTypesPolicy ? trustedTypesPolicy.createHTML('') : '';
259
+ var emptyHTML = trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML('') : '';
259
260
 
260
261
  var _document = document,
261
262
  implementation = _document.implementation,
@@ -265,12 +266,14 @@ function createDOMPurify() {
265
266
  var importNode = originalDocument.importNode;
266
267
 
267
268
 
269
+ var documentMode = clone(document).documentMode ? document.documentMode : {};
270
+
268
271
  var hooks = {};
269
272
 
270
273
  /**
271
274
  * Expose whether this browser supports running the full DOMPurify.
272
275
  */
273
- DOMPurify.isSupported = implementation && typeof implementation.createHTMLDocument !== 'undefined' && document.documentMode !== 9;
276
+ DOMPurify.isSupported = implementation && typeof implementation.createHTMLDocument !== 'undefined' && documentMode !== 9;
274
277
 
275
278
  var MUSTACHE_EXPR$$1 = MUSTACHE_EXPR,
276
279
  ERB_EXPR$$1 = ERB_EXPR,
@@ -343,7 +346,7 @@ function createDOMPurify() {
343
346
  * DOMPurify. */
344
347
  var RETURN_DOM_IMPORT = false;
345
348
 
346
- /* Try to return a Trusted Type object instead of a string, retrun a string in
349
+ /* Try to return a Trusted Type object instead of a string, return a string in
347
350
  * case Trusted Types are not supported */
348
351
  var RETURN_TRUSTED_TYPE = false;
349
352
 
@@ -395,6 +398,9 @@ function createDOMPurify() {
395
398
  cfg = {};
396
399
  }
397
400
 
401
+ /* Shield configuration object from prototype pollution */
402
+ cfg = clone(cfg);
403
+
398
404
  /* Set configuration parameters */
399
405
  ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS) : DEFAULT_ALLOWED_TAGS;
400
406
  ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR) : DEFAULT_ALLOWED_ATTR;
@@ -508,7 +514,6 @@ function createDOMPurify() {
508
514
  var _forceRemove = function _forceRemove(node) {
509
515
  arrayPush(DOMPurify.removed, { element: node });
510
516
  try {
511
- // eslint-disable-next-line unicorn/prefer-node-remove
512
517
  node.parentNode.removeChild(node);
513
518
  } catch (_) {
514
519
  node.outerHTML = emptyHTML;
@@ -678,6 +683,12 @@ function createDOMPurify() {
678
683
  return true;
679
684
  }
680
685
 
686
+ /* Check if tagname contains Unicode */
687
+ if (stringMatch(currentNode.nodeName, /[\u0080-\uFFFF]/)) {
688
+ _forceRemove(currentNode);
689
+ return true;
690
+ }
691
+
681
692
  /* Now let's check the element's type and name */
682
693
  var tagName = stringToLowerCase(currentNode.nodeName);
683
694
 
@@ -695,7 +706,7 @@ function createDOMPurify() {
695
706
 
696
707
  /* Remove element if anything forbids its presence */
697
708
  if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
698
- /* Keep content except for black-listed elements */
709
+ /* Keep content except for bad-listed elements */
699
710
  if (KEEP_CONTENT && !FORBID_CONTENTS[tagName] && typeof currentNode.insertAdjacentHTML === 'function') {
700
711
  try {
701
712
  var htmlToInsert = currentNode.innerHTML;
@@ -719,7 +730,7 @@ function createDOMPurify() {
719
730
  }
720
731
 
721
732
  /* Convert markup to cover jQuery behavior */
722
- if (SAFE_FOR_JQUERY && !currentNode.firstElementChild && (!currentNode.content || !currentNode.content.firstElementChild) && regExpTest(/</g, currentNode.textContent)) {
733
+ if (SAFE_FOR_JQUERY && !_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/</g, currentNode.textContent)) {
723
734
  arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });
724
735
  if (currentNode.innerHTML) {
725
736
  currentNode.innerHTML = stringReplace(currentNode.innerHTML, /</g, '&lt;');
@@ -1020,10 +1031,10 @@ function createDOMPurify() {
1020
1031
  }
1021
1032
  } else {
1022
1033
  /* Exit directly if we have nothing to do */
1023
- if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && RETURN_TRUSTED_TYPE &&
1034
+ if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&
1024
1035
  // eslint-disable-next-line unicorn/prefer-includes
1025
1036
  dirty.indexOf('<') === -1) {
1026
- return trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
1037
+ return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
1027
1038
  }
1028
1039
 
1029
1040
  /* Initialize the document to work on */