sanitize-html 2.4.0 → 2.5.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.5.0 (2021-09-08):
4
+
5
+ - New `allowedScriptHostnames` option, it enables you to specify which hostnames are allowed in a script tag.
6
+ - New `allowedScriptDomains` option, it enables you to specify which domains are allowed in a script tag. Thank you to [Yorick Girard](https://github.com/yorickgirard) for this and the `allowedScriptHostnames` contribution.
7
+ - Updates whitelist to allowlist.
8
+
3
9
  ## 2.4.0 (2021-05-19):
4
10
  - Added support for class names with wildcards in `allowedClasses`. Thanks to [zhangbenber](https://github.com/zhangbenber) for the contribution.
5
11
 
package/README.md CHANGED
@@ -29,7 +29,7 @@ sanitize-html is intended for use with Node.js and supports Node 10+. All of its
29
29
  ### Regarding TypeScript
30
30
 
31
31
  sanitize-html is not written in TypeScript and there is no plan to directly support it. There is a community supported typing definition, [`@types/sanitize-html`](https://www.npmjs.com/package/@types/sanitize-html), however.
32
- ```bash
32
+ ```bash
33
33
  npm install -D @types/sanitize-html
34
34
  ```
35
35
  If `esModuleInterop=true` is not set in your `tsconfig.json` file, you have to import it with:
@@ -51,7 +51,7 @@ But, perhaps you'd like to display sanitized HTML immediately in the browser for
51
51
  * Install the package:
52
52
 
53
53
  ```bash
54
- npm install sanitize-html
54
+ npm install sanitize-html
55
55
  ```
56
56
  or
57
57
  ```
@@ -247,7 +247,7 @@ allowedClasses: {
247
247
 
248
248
  ### Allowed CSS Styles
249
249
 
250
- If you wish to allow specific CSS _styles_ on a particular element, you can do that with the `allowedStyles` option. Simply declare your desired attributes as regular expression options within an array for the given attribute. Specific elements will inherit whitelisted attributes from the global (`*`) attribute. Any other CSS classes are discarded.
250
+ If you wish to allow specific CSS _styles_ on a particular element, you can do that with the `allowedStyles` option. Simply declare your desired attributes as regular expression options within an array for the given attribute. Specific elements will inherit allowlisted attributes from the global (`*`) attribute. Any other CSS classes are discarded.
251
251
 
252
252
  **You must also use `allowedAttributes`** to activate the `style` attribute for the relevant elements. Otherwise this feature will never come into play.
253
253
 
@@ -516,6 +516,32 @@ const clean = sanitizeHtml('<p><iframe src="https://us02web.zoom.us/embed/12345"
516
516
  });
517
517
  ```
518
518
 
519
+ ### Script Filters
520
+
521
+ Similarly to iframes you can allow a script tag on a list of allowlisted domains
522
+
523
+ ```js
524
+ const clean = sanitizeHtml('<script src="https://www.safe.authorized.com/lib.js"></script>', {
525
+ allowedTags: ['script'],
526
+ allowedAttributes: {
527
+ script: ['src']
528
+ },
529
+ allowedScriptDomains: ['authorized.com'],
530
+ })
531
+ ```
532
+
533
+ You can allow a script tag on a list of allowlisted hostnames too
534
+
535
+ ```js
536
+ const clean = sanitizeHtml('<script src="https://www.authorized.com/lib.js"></script>', {
537
+ allowedTags: ['script'],
538
+ allowedAttributes: {
539
+ script: ['src']
540
+ },
541
+ allowedScriptHostnames: [ 'www.authorized.com' ],
542
+ })
543
+ ```
544
+
519
545
  ### Allowed URL schemes
520
546
 
521
547
  By default, we allow the following URL schemes in cases where `href`, `src`, etc. are allowed:
package/index.js CHANGED
@@ -315,6 +315,33 @@ function sanitizeHtml(html, options, _recursing) {
315
315
  return;
316
316
  }
317
317
  }
318
+ if (name === 'script' && a === 'src') {
319
+ let allowed = true;
320
+
321
+ frame.innerText = '';
322
+
323
+ try {
324
+ const parsed = new URL(value);
325
+
326
+ if (options.allowedScriptHostnames || options.allowedScriptDomains) {
327
+ const allowedHostname = (options.allowedScriptHostnames || []).find(function (hostname) {
328
+ return hostname === parsed.hostname;
329
+ });
330
+ const allowedDomain = (options.allowedScriptDomains || []).find(function(domain) {
331
+ return parsed.hostname === domain || parsed.hostname.endsWith(`.${domain}`);
332
+ });
333
+ allowed = allowedHostname || allowedDomain;
334
+ }
335
+ } catch (e) {
336
+ allowed = false;
337
+ }
338
+
339
+ if (!allowed) {
340
+ delete frame.attribs[a];
341
+ return;
342
+ }
343
+ }
344
+
318
345
  if (name === 'iframe' && a === 'src') {
319
346
  let allowed = true;
320
347
  try {
@@ -611,7 +638,7 @@ function sanitizeHtml(html, options, _recursing) {
611
638
  }
612
639
 
613
640
  /**
614
- * Filters user input css properties by whitelisted regex attributes.
641
+ * Filters user input css properties by allowlisted regex attributes.
615
642
  *
616
643
  * @param {object} abstractSyntaxTree - Object representation of CSS attributes.
617
644
  * @property {array[Declaration]} abstractSyntaxTree.nodes[0] - Each object cointains prop and value key, i.e { prop: 'color', value: 'red' }.
@@ -664,10 +691,10 @@ function sanitizeHtml(html, options, _recursing) {
664
691
 
665
692
  /**
666
693
  * Filters the existing attributes for the given property. Discards any attributes
667
- * which don't match the whitelist.
694
+ * which don't match the allowlist.
668
695
  *
669
696
  * @param {object} selectedRule - Example: { color: red, font-family: helvetica }
670
- * @param {array} allowedDeclarationsList - List of declarations which pass whitelisting.
697
+ * @param {array} allowedDeclarationsList - List of declarations which pass the allowlist.
671
698
  * @param {object} attributeObject - Object representing the current css property.
672
699
  * @property {string} attributeObject.type - Typically 'declaration'.
673
700
  * @property {string} attributeObject.prop - The CSS property, i.e 'color'.
@@ -676,7 +703,7 @@ function sanitizeHtml(html, options, _recursing) {
676
703
  */
677
704
  function filterDeclarations(selectedRule) {
678
705
  return function (allowedDeclarationsList, attributeObject) {
679
- // If this property is whitelisted...
706
+ // If this property is allowlisted...
680
707
  if (has(selectedRule, attributeObject.prop)) {
681
708
  const matchesRegex = selectedRule[attributeObject.prop].some(function(regularExpression) {
682
709
  return regularExpression.test(attributeObject.value);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sanitize-html",
3
- "version": "2.4.0",
4
- "description": "Clean up user-submitted HTML, preserving whitelisted elements and whitelisted attributes on a per-element basis",
3
+ "version": "2.5.0",
4
+ "description": "Clean up user-submitted HTML, preserving allowlisted elements and allowlisted attributes on a per-element basis",
5
5
  "sideEffects": false,
6
6
  "main": "index.js",
7
7
  "files": [