dompurify 2.3.8 → 2.3.11

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.
@@ -0,0 +1,144 @@
1
+ export { purify as default };
2
+ declare function purify(root: any): {
3
+ (root: any): any;
4
+ /**
5
+ * Version label, exposed for easier checks
6
+ * if DOMPurify is up to date or not
7
+ */
8
+ version: string;
9
+ /**
10
+ * Array of elements that DOMPurify removed during sanitation.
11
+ * Empty if nothing was removed.
12
+ */
13
+ removed: any[];
14
+ isSupported: boolean;
15
+ /**
16
+ * Sanitize
17
+ * Public method providing core sanitation functionality
18
+ *
19
+ * @param {String|Node} dirty string or DOM node
20
+ * @param {Object} configuration object
21
+ */
22
+ sanitize(dirty: string | Node, cfg: any): any;
23
+ /**
24
+ * Public method to set the configuration once
25
+ * setConfig
26
+ *
27
+ * @param {Object} cfg configuration object
28
+ */
29
+ setConfig(cfg: any): void;
30
+ /**
31
+ * Public method to remove the configuration
32
+ * clearConfig
33
+ *
34
+ */
35
+ clearConfig(): void;
36
+ /**
37
+ * Public method to check if an attribute value is valid.
38
+ * Uses last set config, if any. Otherwise, uses config defaults.
39
+ * isValidAttribute
40
+ *
41
+ * @param {string} tag Tag name of containing element.
42
+ * @param {string} attr Attribute name.
43
+ * @param {string} value Attribute value.
44
+ * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.
45
+ */
46
+ isValidAttribute(tag: string, attr: string, value: string): boolean;
47
+ /**
48
+ * AddHook
49
+ * Public method to add DOMPurify hooks
50
+ *
51
+ * @param {String} entryPoint entry point for the hook to add
52
+ * @param {Function} hookFunction function to execute
53
+ */
54
+ addHook(entryPoint: string, hookFunction: Function): void;
55
+ /**
56
+ * RemoveHook
57
+ * Public method to remove a DOMPurify hook at a given entryPoint
58
+ * (pops it from the stack of hooks if more are present)
59
+ *
60
+ * @param {String} entryPoint entry point for the hook to remove
61
+ * @return {Function} removed(popped) hook
62
+ */
63
+ removeHook(entryPoint: string): Function;
64
+ /**
65
+ * RemoveHooks
66
+ * Public method to remove all DOMPurify hooks at a given entryPoint
67
+ *
68
+ * @param {String} entryPoint entry point for the hooks to remove
69
+ */
70
+ removeHooks(entryPoint: string): void;
71
+ /**
72
+ * RemoveAllHooks
73
+ * Public method to remove all DOMPurify hooks
74
+ *
75
+ */
76
+ removeAllHooks(): void;
77
+ };
78
+ declare namespace purify {
79
+ const version: string;
80
+ const removed: any[];
81
+ const isSupported: boolean;
82
+ /**
83
+ * Sanitize
84
+ * Public method providing core sanitation functionality
85
+ *
86
+ * @param {String|Node} dirty string or DOM node
87
+ * @param {Object} configuration object
88
+ */
89
+ function sanitize(dirty: string | Node, cfg: any): any;
90
+ /**
91
+ * Public method to set the configuration once
92
+ * setConfig
93
+ *
94
+ * @param {Object} cfg configuration object
95
+ */
96
+ function setConfig(cfg: any): void;
97
+ /**
98
+ * Public method to remove the configuration
99
+ * clearConfig
100
+ *
101
+ */
102
+ function clearConfig(): void;
103
+ /**
104
+ * Public method to check if an attribute value is valid.
105
+ * Uses last set config, if any. Otherwise, uses config defaults.
106
+ * isValidAttribute
107
+ *
108
+ * @param {string} tag Tag name of containing element.
109
+ * @param {string} attr Attribute name.
110
+ * @param {string} value Attribute value.
111
+ * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.
112
+ */
113
+ function isValidAttribute(tag: string, attr: string, value: string): boolean;
114
+ /**
115
+ * AddHook
116
+ * Public method to add DOMPurify hooks
117
+ *
118
+ * @param {String} entryPoint entry point for the hook to add
119
+ * @param {Function} hookFunction function to execute
120
+ */
121
+ function addHook(entryPoint: string, hookFunction: Function): void;
122
+ /**
123
+ * RemoveHook
124
+ * Public method to remove a DOMPurify hook at a given entryPoint
125
+ * (pops it from the stack of hooks if more are present)
126
+ *
127
+ * @param {String} entryPoint entry point for the hook to remove
128
+ * @return {Function} removed(popped) hook
129
+ */
130
+ function removeHook(entryPoint: string): Function;
131
+ /**
132
+ * RemoveHooks
133
+ * Public method to remove all DOMPurify hooks at a given entryPoint
134
+ *
135
+ * @param {String} entryPoint entry point for the hooks to remove
136
+ */
137
+ function removeHooks(entryPoint: string): void;
138
+ /**
139
+ * RemoveAllHooks
140
+ * Public method to remove all DOMPurify hooks
141
+ *
142
+ */
143
+ function removeAllHooks(): void;
144
+ }
package/dist/purify.es.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! @license DOMPurify 2.3.8 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.8/LICENSE */
1
+ /*! @license DOMPurify 2.3.11 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.11/LICENSE */
2
2
 
3
3
  function _typeof(obj) {
4
4
  "@babel/helpers - typeof";
@@ -149,7 +149,9 @@ function unconstruct(func) {
149
149
  }
150
150
  /* Add properties to a lookup table */
151
151
 
152
- function addToSet(set, array) {
152
+ function addToSet(set, array, transformCaseFunc) {
153
+ transformCaseFunc = transformCaseFunc ? transformCaseFunc : stringToLowerCase;
154
+
153
155
  if (setPrototypeOf) {
154
156
  // Make 'in' and truthy checks like Boolean(set.constructor)
155
157
  // independent of any properties defined on Object.prototype.
@@ -163,7 +165,7 @@ function addToSet(set, array) {
163
165
  var element = array[l];
164
166
 
165
167
  if (typeof element === 'string') {
166
- var lcElement = stringToLowerCase(element);
168
+ var lcElement = transformCaseFunc(element);
167
169
 
168
170
  if (lcElement !== element) {
169
171
  // Config presets (e.g. tags.js, attrs.js) are immutable.
@@ -292,6 +294,9 @@ var _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes,
292
294
  return trustedTypes.createPolicy(policyName, {
293
295
  createHTML: function createHTML(html) {
294
296
  return html;
297
+ },
298
+ createScriptURL: function createScriptURL(scriptUrl) {
299
+ return scriptUrl;
295
300
  }
296
301
  });
297
302
  } catch (_) {
@@ -315,7 +320,7 @@ function createDOMPurify() {
315
320
  */
316
321
 
317
322
 
318
- DOMPurify.version = '2.3.8';
323
+ DOMPurify.version = '2.3.11';
319
324
  /**
320
325
  * Array of elements that DOMPurify removed during sanitation.
321
326
  * Empty if nothing was removed.
@@ -473,9 +478,27 @@ function createDOMPurify() {
473
478
  * case Trusted Types are not supported */
474
479
 
475
480
  var RETURN_TRUSTED_TYPE = false;
476
- /* Output should be free from DOM clobbering attacks? */
481
+ /* Output should be free from DOM clobbering attacks?
482
+ * This sanitizes markups named with colliding, clobberable built-in DOM APIs.
483
+ */
477
484
 
478
485
  var SANITIZE_DOM = true;
486
+ /* Achieve full DOM Clobbering protection by isolating the namespace of named
487
+ * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.
488
+ *
489
+ * HTML/DOM spec rules that enable DOM Clobbering:
490
+ * - Named Access on Window (§7.3.3)
491
+ * - DOM Tree Accessors (§3.1.5)
492
+ * - Form Element Parent-Child Relations (§4.10.3)
493
+ * - Iframe srcdoc / Nested WindowProxies (§4.8.5)
494
+ * - HTMLCollection (§4.2.10.2)
495
+ *
496
+ * Namespace isolation is implemented by prefixing `id` and `name` attributes
497
+ * with a constant string, i.e., `user-content-`
498
+ */
499
+
500
+ var SANITIZE_NAMED_PROPS = false;
501
+ var SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';
479
502
  /* Keep element content when removing element? */
480
503
 
481
504
  var KEEP_CONTENT = true;
@@ -545,15 +568,29 @@ function createDOMPurify() {
545
568
 
546
569
 
547
570
  cfg = clone(cfg);
571
+ PARSER_MEDIA_TYPE = // eslint-disable-next-line unicorn/prefer-includes
572
+ SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE : PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE; // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
573
+
574
+ transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? function (x) {
575
+ return x;
576
+ } : stringToLowerCase;
548
577
  /* Set configuration parameters */
549
578
 
550
- ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS) : DEFAULT_ALLOWED_TAGS;
551
- ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR) : DEFAULT_ALLOWED_ATTR;
552
- URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR) : DEFAULT_URI_SAFE_ATTRIBUTES;
553
- DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS) : DEFAULT_DATA_URI_TAGS;
554
- FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS) : DEFAULT_FORBID_CONTENTS;
555
- FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS) : {};
556
- FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR) : {};
579
+ ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
580
+ ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
581
+ URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), // eslint-disable-line indent
582
+ cfg.ADD_URI_SAFE_ATTR, // eslint-disable-line indent
583
+ transformCaseFunc // eslint-disable-line indent
584
+ ) // eslint-disable-line indent
585
+ : DEFAULT_URI_SAFE_ATTRIBUTES;
586
+ DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS), // eslint-disable-line indent
587
+ cfg.ADD_DATA_URI_TAGS, // eslint-disable-line indent
588
+ transformCaseFunc // eslint-disable-line indent
589
+ ) // eslint-disable-line indent
590
+ : DEFAULT_DATA_URI_TAGS;
591
+ FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
592
+ FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {};
593
+ FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};
557
594
  USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;
558
595
  ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
559
596
 
@@ -575,6 +612,8 @@ function createDOMPurify() {
575
612
 
576
613
  SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
577
614
 
615
+ SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false
616
+
578
617
  KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
579
618
 
580
619
  IN_PLACE = cfg.IN_PLACE || false; // Default false
@@ -594,13 +633,6 @@ function createDOMPurify() {
594
633
  CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;
595
634
  }
596
635
 
597
- PARSER_MEDIA_TYPE = // eslint-disable-next-line unicorn/prefer-includes
598
- SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE : PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE; // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
599
-
600
- transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? function (x) {
601
- return x;
602
- } : stringToLowerCase;
603
-
604
636
  if (SAFE_FOR_TEMPLATES) {
605
637
  ALLOW_DATA_ATTR = false;
606
638
  }
@@ -646,7 +678,7 @@ function createDOMPurify() {
646
678
  ALLOWED_TAGS = clone(ALLOWED_TAGS);
647
679
  }
648
680
 
649
- addToSet(ALLOWED_TAGS, cfg.ADD_TAGS);
681
+ addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
650
682
  }
651
683
 
652
684
  if (cfg.ADD_ATTR) {
@@ -654,11 +686,11 @@ function createDOMPurify() {
654
686
  ALLOWED_ATTR = clone(ALLOWED_ATTR);
655
687
  }
656
688
 
657
- addToSet(ALLOWED_ATTR, cfg.ADD_ATTR);
689
+ addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
658
690
  }
659
691
 
660
692
  if (cfg.ADD_URI_SAFE_ATTR) {
661
- addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR);
693
+ addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
662
694
  }
663
695
 
664
696
  if (cfg.FORBID_CONTENTS) {
@@ -666,7 +698,7 @@ function createDOMPurify() {
666
698
  FORBID_CONTENTS = clone(FORBID_CONTENTS);
667
699
  }
668
700
 
669
- addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS);
701
+ addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
670
702
  }
671
703
  /* Add #text in case KEEP_CONTENT is set to true */
672
704
 
@@ -1238,6 +1270,34 @@ function createDOMPurify() {
1238
1270
  if (!_isValidAttribute(lcTag, lcName, value)) {
1239
1271
  continue;
1240
1272
  }
1273
+ /* Full DOM Clobbering protection via namespace isolation,
1274
+ * Prefix id and name attributes with `user-content-`
1275
+ */
1276
+
1277
+
1278
+ if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {
1279
+ // Remove the attribute with this value
1280
+ _removeAttribute(name, currentNode); // Prefix the value and later re-create the attribute with the sanitized value
1281
+
1282
+
1283
+ value = SANITIZE_NAMED_PROPS_PREFIX + value;
1284
+ }
1285
+ /* Handle attributes that require Trusted Types */
1286
+
1287
+
1288
+ if (trustedTypesPolicy && _typeof(trustedTypes) === 'object' && typeof trustedTypes.getAttributeType === 'function') {
1289
+ if (namespaceURI) ; else {
1290
+ switch (trustedTypes.getAttributeType(lcTag, lcName)) {
1291
+ case 'TrustedHTML':
1292
+ value = trustedTypesPolicy.createHTML(value);
1293
+ break;
1294
+
1295
+ case 'TrustedScriptURL':
1296
+ value = trustedTypesPolicy.createScriptURL(value);
1297
+ break;
1298
+ }
1299
+ }
1300
+ }
1241
1301
  /* Handle invalid data-* attribute set by try-catching it */
1242
1302
 
1243
1303