dompurify 2.0.8 → 2.0.12
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 +34 -21
- package/dist/purify.cjs.js +56 -94
- package/dist/purify.cjs.js.map +1 -1
- package/dist/purify.es.js +56 -94
- package/dist/purify.es.js.map +1 -1
- package/dist/purify.js +1002 -1040
- package/dist/purify.js.map +1 -1
- package/dist/purify.min.js +2 -1
- package/dist/purify.min.js.map +1 -1
- package/package.json +20 -17
package/README.md
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# DOMPurify
|
|
2
2
|
|
|
3
|
-
[](http://badge.fury.io/bo/dompurify)
|
|
3
|
+
[](http://badge.fury.io/bo/dompurify) [](http://badge.fury.io/js/dompurify)  [](https://www.npmjs.com/package/dompurify) [](https://cdn.jsdelivr.net/npm/dompurify/dist/purify.min.js) [](https://packagephobia.now.sh/result?p=dompurify)
|
|
4
4
|
|
|
5
5
|
[](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.
|
|
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.12.
|
|
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/
|
|
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
|
|
|
@@ -36,23 +36,31 @@ It's easy. Just include DOMPurify on your website.
|
|
|
36
36
|
|
|
37
37
|
Afterwards you can sanitize strings by executing the following code:
|
|
38
38
|
|
|
39
|
-
```
|
|
39
|
+
```js
|
|
40
40
|
var clean = DOMPurify.sanitize(dirty);
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
The resulting HTML can be written into a DOM element using `innerHTML` or the DOM using `document.write()`. That is fully up to you. But keep in mind, if you use the sanitized HTML with jQuery's very insecure `elm.html()` method, then the `SAFE_FOR_JQUERY` flag has to be set to make sure it's safe! Other than that, all is fine.
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
### Is there any foot-gun potential?
|
|
46
|
+
|
|
47
|
+
Well, please note, if you _first_ sanitize HTML and then modify it _afterwards_, you might easily **void the effects of sanitization**. If you feed the sanitized markup to another library _after_ sanitization, please be certain that the library doesn't mess around with the HTML on its own.
|
|
48
|
+
|
|
49
|
+
jQuery does exactly that and that is why we have this flag mentioned above.
|
|
50
|
+
|
|
51
|
+
### Okay, makes sense, let's move on
|
|
52
|
+
|
|
53
|
+
After sanitizing your markup, you can also have a look at the property `DOMPurify.removed` and find out, what elements and attributes were thrown out. Please **do not use** this property for making any security critical decisions. This is just a little helper for curious minds.
|
|
46
54
|
|
|
47
55
|
If you're using an [AMD](https://github.com/amdjs/amdjs-api/wiki/AMD) module loader like [Require.js](http://requirejs.org/), you can load this script asynchronously as well:
|
|
48
56
|
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
57
|
+
```js
|
|
58
|
+
import DOMPurify from 'dompurify';
|
|
59
|
+
|
|
60
|
+
var clean = DOMPurify.sanitize(dirty);
|
|
53
61
|
```
|
|
54
62
|
|
|
55
|
-
DOMPurify also works server-side with
|
|
63
|
+
DOMPurify also works server-side with Node.js as well as client-side via [Browserify](http://browserify.org/) or similar translators. At least Node.js 4.x or newer is required. Our support strives to follow the [Node.js release cycle](https://nodejs.org/en/about/releases/). DOMPurify intends to support any version being flagged as active. At the same time we phase out support for any version flagged as maintenance. DOMPurify might not break with all versions in maintenance immediately but stops to run tests against these older versions.
|
|
56
64
|
|
|
57
65
|
```bash
|
|
58
66
|
npm install dompurify
|
|
@@ -60,7 +68,7 @@ npm install dompurify
|
|
|
60
68
|
|
|
61
69
|
For JSDOM v10 or newer
|
|
62
70
|
|
|
63
|
-
```
|
|
71
|
+
```js
|
|
64
72
|
const createDOMPurify = require('dompurify');
|
|
65
73
|
const { JSDOM } = require('jsdom');
|
|
66
74
|
|
|
@@ -72,7 +80,7 @@ const clean = DOMPurify.sanitize(dirty);
|
|
|
72
80
|
|
|
73
81
|
For JSDOM versions older than v10
|
|
74
82
|
|
|
75
|
-
```
|
|
83
|
+
```js
|
|
76
84
|
const createDOMPurify = require('dompurify');
|
|
77
85
|
const jsdom = require('jsdom').jsdom;
|
|
78
86
|
|
|
@@ -96,10 +104,10 @@ Also, you probably qualify for a bug bounty! The fine folks over at [FastMail](h
|
|
|
96
104
|
|
|
97
105
|
How does purified markup look like? Well, [the demo](https://cure53.de/purify) shows it for a big bunch of nasty elements. But let's also show some smaller examples!
|
|
98
106
|
|
|
99
|
-
```
|
|
107
|
+
```js
|
|
100
108
|
DOMPurify.sanitize('<img src=x onerror=alert(1)//>'); // becomes <img src="x">
|
|
101
109
|
DOMPurify.sanitize('<svg><g/onload=alert(2)//<p>'); // becomes <svg><g></g></svg>
|
|
102
|
-
DOMPurify.sanitize('<p>abc<iframe//src=jAva	script:alert(3)>def'); // becomes <p>abcdef</p>
|
|
110
|
+
DOMPurify.sanitize('<p>abc<iframe//src=jAva	script:alert(3)>def</p>'); // becomes <p>abcdef</p>
|
|
103
111
|
DOMPurify.sanitize('<math><mi//xlink:href="data:x,<script>alert(4)</script>">'); // becomes <math><mi></mi></math>
|
|
104
112
|
DOMPurify.sanitize('<TABLE><tr><td>HELLO</tr></TABL>'); // becomes <table><tbody><tr><td>HELLO</td></tr></tbody></table>
|
|
105
113
|
DOMPurify.sanitize('<UL><li><A HREF=//google.com>click</UL>'); // becomes <ul><li><a href="//google.com">click</a></li></ul>
|
|
@@ -115,6 +123,8 @@ DOMPurify offers a fall-back behavior for older MSIE browsers. It uses the MSIE-
|
|
|
115
123
|
|
|
116
124
|
If not even `toStaticHTML` is supported, DOMPurify does nothing at all. It simply returns exactly the string that you fed it.
|
|
117
125
|
|
|
126
|
+
DOMPurify also exposes a property called `isSupported`, which tells you whether DOMPurify will be able to do its job.
|
|
127
|
+
|
|
118
128
|
## What about DOMPurify and Trusted Types?
|
|
119
129
|
|
|
120
130
|
In version 1.0.9, support for [Trusted Types API](https://github.com/WICG/trusted-types) was added to DOMPurify.
|
|
@@ -124,9 +134,9 @@ When `DOMPurify.sanitize` is used in an environment where the Trusted Types API
|
|
|
124
134
|
|
|
125
135
|
## Can I configure DOMPurify?
|
|
126
136
|
|
|
127
|
-
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/
|
|
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).
|
|
128
138
|
|
|
129
|
-
```
|
|
139
|
+
```js
|
|
130
140
|
// make output safe for usage in jQuery's $()/html() method (default is false)
|
|
131
141
|
var clean = DOMPurify.sanitize(dirty, {SAFE_FOR_JQUERY: true});
|
|
132
142
|
|
|
@@ -163,6 +173,9 @@ var clean = DOMPurify.sanitize(dirty, {ADD_TAGS: ['my-tag']});
|
|
|
163
173
|
// extend the existing array of attributes
|
|
164
174
|
var clean = DOMPurify.sanitize(dirty, {ADD_ATTR: ['my-attr']});
|
|
165
175
|
|
|
176
|
+
// extend the existing array of tags that can use Data URIs
|
|
177
|
+
var clean = DOMPurify.sanitize(dirty, {ADD_DATA_URI_TAGS: ['a', 'area']});
|
|
178
|
+
|
|
166
179
|
// prohibit HTML5 data attributes (default is true)
|
|
167
180
|
var clean = DOMPurify.sanitize(dirty, {ALLOW_DATA_ATTR: false});
|
|
168
181
|
|
|
@@ -209,7 +222,7 @@ dirty.setAttribute('href', 'javascript:alert(1)');
|
|
|
209
222
|
var clean = DOMPurify.sanitize(dirty, {IN_PLACE: true}); // see https://github.com/cure53/DOMPurify/issues/288 for more info
|
|
210
223
|
```
|
|
211
224
|
|
|
212
|
-
There is even [more examples here](https://github.com/cure53/DOMPurify/tree/
|
|
225
|
+
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.
|
|
213
226
|
|
|
214
227
|
## Persistent Configuration
|
|
215
228
|
|
|
@@ -229,12 +242,12 @@ DOMPurify allows you to augment its functionality by attaching one or more funct
|
|
|
229
242
|
- `uponSanitizeShadowNode`
|
|
230
243
|
- `afterSanitizeShadowDOM`
|
|
231
244
|
|
|
232
|
-
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/
|
|
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/main/demos/hooks-mentaljs-demo.html) to see how the API can be used nicely.
|
|
233
246
|
|
|
234
247
|
_Example_:
|
|
235
248
|
|
|
236
|
-
```
|
|
237
|
-
DOMPurify.addHook('beforeSanitizeElements', function(
|
|
249
|
+
```js
|
|
250
|
+
DOMPurify.addHook('beforeSanitizeElements', function (
|
|
238
251
|
currentNode,
|
|
239
252
|
hookEvent,
|
|
240
253
|
config
|
|
@@ -291,6 +304,6 @@ Feature releases will not be announced to this list.
|
|
|
291
304
|
|
|
292
305
|
Many people helped and help DOMPurify become what it is and need to be acknowledged here!
|
|
293
306
|
|
|
294
|
-
[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)
|
|
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)
|
|
295
308
|
|
|
296
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.
|
package/dist/purify.cjs.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
+
/*! @license DOMPurify | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.0.8/LICENSE */
|
|
2
|
+
|
|
1
3
|
'use strict';
|
|
2
4
|
|
|
3
|
-
function _toConsumableArray
|
|
5
|
+
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
|
4
6
|
|
|
5
|
-
var hasOwnProperty = Object.hasOwnProperty
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
var freeze = Object.freeze
|
|
10
|
-
|
|
7
|
+
var hasOwnProperty = Object.hasOwnProperty,
|
|
8
|
+
setPrototypeOf = Object.setPrototypeOf,
|
|
9
|
+
isFrozen = Object.isFrozen,
|
|
10
|
+
objectKeys = Object.keys;
|
|
11
|
+
var freeze = Object.freeze,
|
|
12
|
+
seal = Object.seal; // eslint-disable-line import/no-mutable-exports
|
|
11
13
|
|
|
12
|
-
var _ref = typeof Reflect !== 'undefined' && Reflect
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
var _ref = typeof Reflect !== 'undefined' && Reflect,
|
|
15
|
+
apply = _ref.apply,
|
|
16
|
+
construct = _ref.construct;
|
|
15
17
|
|
|
16
18
|
if (!apply) {
|
|
17
19
|
apply = function apply(fun, thisValue, args) {
|
|
@@ -33,7 +35,7 @@ if (!seal) {
|
|
|
33
35
|
|
|
34
36
|
if (!construct) {
|
|
35
37
|
construct = function construct(Func, args) {
|
|
36
|
-
return new (Function.prototype.bind.apply(Func, [null].concat(_toConsumableArray
|
|
38
|
+
return new (Function.prototype.bind.apply(Func, [null].concat(_toConsumableArray(args))))();
|
|
37
39
|
};
|
|
38
40
|
}
|
|
39
41
|
|
|
@@ -130,14 +132,15 @@ var mathMl = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph',
|
|
|
130
132
|
|
|
131
133
|
var text = freeze(['#text']);
|
|
132
134
|
|
|
133
|
-
var html$1 = freeze(['accept', 'action', 'align', 'alt', 'autocomplete', 'background', 'bgcolor', 'border', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'coords', 'crossorigin', 'datetime', 'default', 'dir', 'disabled', 'download', 'enctype', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'integrity', 'ismap', 'label', 'lang', 'list', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'name', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', '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', 'type', 'usemap', 'valign', 'value', 'width', 'xmlns']);
|
|
135
|
+
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']);
|
|
134
136
|
|
|
135
|
-
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', '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']);
|
|
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']);
|
|
136
138
|
|
|
137
139
|
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']);
|
|
138
140
|
|
|
139
141
|
var xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
|
|
140
142
|
|
|
143
|
+
// eslint-disable-next-line unicorn/better-regex
|
|
141
144
|
var MUSTACHE_EXPR = seal(/\{\{[\s\S]*|[\s\S]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
|
|
142
145
|
var ERB_EXPR = seal(/<%[\s\S]*|[\s\S]*%>/gm);
|
|
143
146
|
var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); // eslint-disable-line no-useless-escape
|
|
@@ -150,7 +153,7 @@ var ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205f\
|
|
|
150
153
|
|
|
151
154
|
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; };
|
|
152
155
|
|
|
153
|
-
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
|
156
|
+
function _toConsumableArray$1(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
|
154
157
|
|
|
155
158
|
var getGlobal = function getGlobal() {
|
|
156
159
|
return typeof window === 'undefined' ? null : window;
|
|
@@ -186,7 +189,7 @@ var _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes,
|
|
|
186
189
|
return html$$1;
|
|
187
190
|
}
|
|
188
191
|
});
|
|
189
|
-
} catch (
|
|
192
|
+
} catch (_) {
|
|
190
193
|
// Policy creation failed (most likely another DOMPurify script has
|
|
191
194
|
// already run). Skip creating the policy, as this will only cause errors
|
|
192
195
|
// if TT are enforced.
|
|
@@ -206,7 +209,7 @@ function createDOMPurify() {
|
|
|
206
209
|
* Version label, exposed for easier checks
|
|
207
210
|
* if DOMPurify is up to date or not
|
|
208
211
|
*/
|
|
209
|
-
DOMPurify.version = '2.0.
|
|
212
|
+
DOMPurify.version = '2.0.12';
|
|
210
213
|
|
|
211
214
|
/**
|
|
212
215
|
* Array of elements that DOMPurify removed during sanitation.
|
|
@@ -223,7 +226,6 @@ function createDOMPurify() {
|
|
|
223
226
|
}
|
|
224
227
|
|
|
225
228
|
var originalDocument = window.document;
|
|
226
|
-
var useDOMParser = false;
|
|
227
229
|
var removeTitle = false;
|
|
228
230
|
|
|
229
231
|
var document = window.document;
|
|
@@ -253,7 +255,7 @@ function createDOMPurify() {
|
|
|
253
255
|
}
|
|
254
256
|
|
|
255
257
|
var trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, originalDocument);
|
|
256
|
-
var emptyHTML = trustedTypesPolicy ? trustedTypesPolicy.createHTML('') : '';
|
|
258
|
+
var emptyHTML = trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML('') : '';
|
|
257
259
|
|
|
258
260
|
var _document = document,
|
|
259
261
|
implementation = _document.implementation,
|
|
@@ -286,11 +288,11 @@ function createDOMPurify() {
|
|
|
286
288
|
/* allowed element names */
|
|
287
289
|
|
|
288
290
|
var ALLOWED_TAGS = null;
|
|
289
|
-
var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray(html), _toConsumableArray(svg), _toConsumableArray(svgFilters), _toConsumableArray(mathMl), _toConsumableArray(text)));
|
|
291
|
+
var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(html), _toConsumableArray$1(svg), _toConsumableArray$1(svgFilters), _toConsumableArray$1(mathMl), _toConsumableArray$1(text)));
|
|
290
292
|
|
|
291
293
|
/* Allowed attribute names */
|
|
292
294
|
var ALLOWED_ATTR = null;
|
|
293
|
-
var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray(html$1), _toConsumableArray(svg$1), _toConsumableArray(mathMl$1), _toConsumableArray(xml)));
|
|
295
|
+
var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray$1(html$1), _toConsumableArray$1(svg$1), _toConsumableArray$1(mathMl$1), _toConsumableArray$1(xml)));
|
|
294
296
|
|
|
295
297
|
/* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
|
|
296
298
|
var FORBID_TAGS = null;
|
|
@@ -362,7 +364,8 @@ function createDOMPurify() {
|
|
|
362
364
|
var FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']);
|
|
363
365
|
|
|
364
366
|
/* Tags that are safe for data: URIs */
|
|
365
|
-
var DATA_URI_TAGS =
|
|
367
|
+
var DATA_URI_TAGS = null;
|
|
368
|
+
var DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);
|
|
366
369
|
|
|
367
370
|
/* Attributes safe for values like "javascript:" */
|
|
368
371
|
var URI_SAFE_ATTRIBUTES = null;
|
|
@@ -396,6 +399,7 @@ function createDOMPurify() {
|
|
|
396
399
|
ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS) : DEFAULT_ALLOWED_TAGS;
|
|
397
400
|
ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR) : DEFAULT_ALLOWED_ATTR;
|
|
398
401
|
URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR) : DEFAULT_URI_SAFE_ATTRIBUTES;
|
|
402
|
+
DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS) : DEFAULT_DATA_URI_TAGS;
|
|
399
403
|
FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS) : {};
|
|
400
404
|
FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR) : {};
|
|
401
405
|
USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;
|
|
@@ -424,7 +428,7 @@ function createDOMPurify() {
|
|
|
424
428
|
|
|
425
429
|
/* Parse profile info */
|
|
426
430
|
if (USE_PROFILES) {
|
|
427
|
-
ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray(text)));
|
|
431
|
+
ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(text)));
|
|
428
432
|
ALLOWED_ATTR = [];
|
|
429
433
|
if (USE_PROFILES.html === true) {
|
|
430
434
|
addToSet(ALLOWED_TAGS, html);
|
|
@@ -504,8 +508,9 @@ function createDOMPurify() {
|
|
|
504
508
|
var _forceRemove = function _forceRemove(node) {
|
|
505
509
|
arrayPush(DOMPurify.removed, { element: node });
|
|
506
510
|
try {
|
|
511
|
+
// eslint-disable-next-line unicorn/prefer-node-remove
|
|
507
512
|
node.parentNode.removeChild(node);
|
|
508
|
-
} catch (
|
|
513
|
+
} catch (_) {
|
|
509
514
|
node.outerHTML = emptyHTML;
|
|
510
515
|
}
|
|
511
516
|
};
|
|
@@ -522,7 +527,7 @@ function createDOMPurify() {
|
|
|
522
527
|
attribute: node.getAttributeNode(name),
|
|
523
528
|
from: node
|
|
524
529
|
});
|
|
525
|
-
} catch (
|
|
530
|
+
} catch (_) {
|
|
526
531
|
arrayPush(DOMPurify.removed, {
|
|
527
532
|
attribute: null,
|
|
528
533
|
from: node
|
|
@@ -547,25 +552,22 @@ function createDOMPurify() {
|
|
|
547
552
|
dirty = '<remove></remove>' + dirty;
|
|
548
553
|
} else {
|
|
549
554
|
/* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */
|
|
550
|
-
var matches = stringMatch(dirty, /^[\
|
|
555
|
+
var matches = stringMatch(dirty, /^[\r\n\t ]+/);
|
|
551
556
|
leadingWhitespace = matches && matches[0];
|
|
552
557
|
}
|
|
553
558
|
|
|
554
559
|
var dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
|
555
|
-
/* Use DOMParser
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
} catch (error) {}
|
|
560
|
-
}
|
|
560
|
+
/* Use the DOMParser API by default, fallback later if needs be */
|
|
561
|
+
try {
|
|
562
|
+
doc = new DOMParser().parseFromString(dirtyPayload, 'text/html');
|
|
563
|
+
} catch (_) {}
|
|
561
564
|
|
|
562
565
|
/* Remove title to fix a mXSS bug in older MS Edge */
|
|
563
566
|
if (removeTitle) {
|
|
564
567
|
addToSet(FORBID_TAGS, ['title']);
|
|
565
568
|
}
|
|
566
569
|
|
|
567
|
-
/*
|
|
568
|
-
Safari (see comment below) */
|
|
570
|
+
/* Use createHTMLDocument in case DOMParser is not available */
|
|
569
571
|
if (!doc || !doc.documentElement) {
|
|
570
572
|
doc = implementation.createHTMLDocument('');
|
|
571
573
|
var _doc = doc,
|
|
@@ -583,32 +585,15 @@ function createDOMPurify() {
|
|
|
583
585
|
return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
|
|
584
586
|
};
|
|
585
587
|
|
|
586
|
-
|
|
587
|
-
// DOMParser (see https://bugzilla.mozilla.org/show_bug.cgi?id=1205631)
|
|
588
|
-
// which means that you *must* use DOMParser, otherwise the output may
|
|
589
|
-
// not be safe if used in a document.write context later.
|
|
590
|
-
//
|
|
591
|
-
// So we feature detect the Firefox bug and use the DOMParser if necessary.
|
|
592
|
-
//
|
|
593
|
-
// Chrome 77 and other versions ship an mXSS bug that caused a bypass to
|
|
594
|
-
// happen. We now check for the mXSS trigger and react accordingly.
|
|
588
|
+
/* Here we test for a broken feature in Edge that might cause mXSS */
|
|
595
589
|
if (DOMPurify.isSupported) {
|
|
596
|
-
(function () {
|
|
597
|
-
try {
|
|
598
|
-
var doc = _initDocument('<svg><p><textarea><img src="</textarea><img src=x abc=1//">');
|
|
599
|
-
if (doc.querySelector('svg img')) {
|
|
600
|
-
useDOMParser = true;
|
|
601
|
-
}
|
|
602
|
-
} catch (error) {}
|
|
603
|
-
})();
|
|
604
|
-
|
|
605
590
|
(function () {
|
|
606
591
|
try {
|
|
607
592
|
var doc = _initDocument('<x/><title></title><img>');
|
|
608
593
|
if (regExpTest(/<\/title/, doc.querySelector('title').innerHTML)) {
|
|
609
594
|
removeTitle = true;
|
|
610
595
|
}
|
|
611
|
-
} catch (
|
|
596
|
+
} catch (_) {}
|
|
612
597
|
})();
|
|
613
598
|
}
|
|
614
599
|
|
|
@@ -648,8 +633,8 @@ function createDOMPurify() {
|
|
|
648
633
|
* @param {Node} obj object to check whether it's a DOM node
|
|
649
634
|
* @return {Boolean} true is object is a DOM node
|
|
650
635
|
*/
|
|
651
|
-
var _isNode = function _isNode(
|
|
652
|
-
return (typeof Node === 'undefined' ? 'undefined' : _typeof(Node)) === 'object' ?
|
|
636
|
+
var _isNode = function _isNode(object) {
|
|
637
|
+
return (typeof Node === 'undefined' ? 'undefined' : _typeof(Node)) === 'object' ? object instanceof Node : object && (typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string';
|
|
653
638
|
};
|
|
654
639
|
|
|
655
640
|
/**
|
|
@@ -710,12 +695,12 @@ function createDOMPurify() {
|
|
|
710
695
|
|
|
711
696
|
/* Remove element if anything forbids its presence */
|
|
712
697
|
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
713
|
-
/* Keep content except for
|
|
698
|
+
/* Keep content except for bad-listed elements */
|
|
714
699
|
if (KEEP_CONTENT && !FORBID_CONTENTS[tagName] && typeof currentNode.insertAdjacentHTML === 'function') {
|
|
715
700
|
try {
|
|
716
701
|
var htmlToInsert = currentNode.innerHTML;
|
|
717
702
|
currentNode.insertAdjacentHTML('AfterEnd', trustedTypesPolicy ? trustedTypesPolicy.createHTML(htmlToInsert) : htmlToInsert);
|
|
718
|
-
} catch (
|
|
703
|
+
} catch (_) {}
|
|
719
704
|
}
|
|
720
705
|
|
|
721
706
|
_forceRemove(currentNode);
|
|
@@ -780,36 +765,11 @@ function createDOMPurify() {
|
|
|
780
765
|
(https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
|
|
781
766
|
XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
|
|
782
767
|
We don't need to check the value; it's always URI safe. */
|
|
783
|
-
if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$$1, lcName)) {
|
|
784
|
-
// This attribute is safe
|
|
785
|
-
} else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$$1, lcName)) {
|
|
786
|
-
// This attribute is safe
|
|
787
|
-
/* Otherwise, check the name is permitted */
|
|
788
|
-
} else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
|
|
768
|
+
if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$$1, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$$1, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
|
|
789
769
|
return false;
|
|
790
770
|
|
|
791
771
|
/* Check value is safe. First, is attr inert? If so, is safe */
|
|
792
|
-
} else if (URI_SAFE_ATTRIBUTES[lcName]) {
|
|
793
|
-
// This attribute is safe
|
|
794
|
-
/* Check no script, data or unknown possibly unsafe URI
|
|
795
|
-
unless we know URI values are safe for that attribute */
|
|
796
|
-
} else if (regExpTest(IS_ALLOWED_URI$$1, stringReplace(value, ATTR_WHITESPACE$$1, ''))) {
|
|
797
|
-
// This attribute is safe
|
|
798
|
-
/* Keep image data URIs alive if src/xlink:href is allowed */
|
|
799
|
-
/* Further prevent gadget XSS for dynamically built script tags */
|
|
800
|
-
} else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) {
|
|
801
|
-
// This attribute is safe
|
|
802
|
-
/* Allow unknown protocols: This provides support for links that
|
|
803
|
-
are handled by protocol handlers which may be unknown ahead of
|
|
804
|
-
time, e.g. fb:, spotify: */
|
|
805
|
-
} else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$$1, stringReplace(value, ATTR_WHITESPACE$$1, ''))) {
|
|
806
|
-
// This attribute is safe
|
|
807
|
-
/* Check for binary attributes */
|
|
808
|
-
// eslint-disable-next-line no-negated-condition
|
|
809
|
-
} else if (!value) {
|
|
810
|
-
// Binary attributes are safe at this point
|
|
811
|
-
/* Anything else, presume unsafe, do not add it back */
|
|
812
|
-
} else {
|
|
772
|
+
} else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$$1, stringReplace(value, ATTR_WHITESPACE$$1, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$$1, stringReplace(value, ATTR_WHITESPACE$$1, ''))) ; else if (!value) ; else {
|
|
813
773
|
return false;
|
|
814
774
|
}
|
|
815
775
|
|
|
@@ -941,7 +901,7 @@ function createDOMPurify() {
|
|
|
941
901
|
}
|
|
942
902
|
|
|
943
903
|
arrayPop(DOMPurify.removed);
|
|
944
|
-
} catch (
|
|
904
|
+
} catch (_) {}
|
|
945
905
|
}
|
|
946
906
|
|
|
947
907
|
/* Execute a hook if present */
|
|
@@ -1044,9 +1004,7 @@ function createDOMPurify() {
|
|
|
1044
1004
|
IN_PLACE = false;
|
|
1045
1005
|
}
|
|
1046
1006
|
|
|
1047
|
-
if (IN_PLACE) {
|
|
1048
|
-
/* No special handling necessary for in-place sanitization */
|
|
1049
|
-
} else if (dirty instanceof Node) {
|
|
1007
|
+
if (IN_PLACE) ; else if (dirty instanceof Node) {
|
|
1050
1008
|
/* If dirty is a DOM element, append to an empty document to avoid
|
|
1051
1009
|
elements being stripped by the parser */
|
|
1052
1010
|
body = _initDocument('<!-->');
|
|
@@ -1062,8 +1020,10 @@ function createDOMPurify() {
|
|
|
1062
1020
|
}
|
|
1063
1021
|
} else {
|
|
1064
1022
|
/* Exit directly if we have nothing to do */
|
|
1065
|
-
if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&
|
|
1066
|
-
|
|
1023
|
+
if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&
|
|
1024
|
+
// eslint-disable-next-line unicorn/prefer-includes
|
|
1025
|
+
dirty.indexOf('<') === -1) {
|
|
1026
|
+
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
|
1067
1027
|
}
|
|
1068
1028
|
|
|
1069
1029
|
/* Initialize the document to work on */
|
|
@@ -1127,11 +1087,13 @@ function createDOMPurify() {
|
|
|
1127
1087
|
}
|
|
1128
1088
|
|
|
1129
1089
|
if (RETURN_DOM_IMPORT) {
|
|
1130
|
-
/*
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1090
|
+
/*
|
|
1091
|
+
AdoptNode() is not used because internal state is not reset
|
|
1092
|
+
(e.g. the past names map of a HTMLFormElement), this is safe
|
|
1093
|
+
in theory but we would rather not risk another attack vector.
|
|
1094
|
+
The state that is cloned by importNode() is explicitly defined
|
|
1095
|
+
by the specs.
|
|
1096
|
+
*/
|
|
1135
1097
|
returnNode = importNode.call(originalDocument, returnNode, true);
|
|
1136
1098
|
}
|
|
1137
1099
|
|