Repository: apostrophecms/sanitize-html (js)
Issue: nonTextTags is not working for script tag
I want to allow `script` tags only with `src` attributes from specific domains, but `nonTextTags: ['script']` option doesn't remove the code contents from it.

Or, is there other way to sanitize script contents?

## To Reproduce

```js
const content = sanitizeHtml('<script src="https://apps.elfsight.com/p/platform.js"></script><script>alert(1)</script>', {
    allowedTags: ['script'],
    allowedAttributes: {
        script: ['src'],
    },
    nonTextTags: ['script'],
    allowedScriptHostnames: ['apps.elfsight.com'],
});
```

## Expected behavior

Should return:
```
<script src="https://apps.elfsight.com/p/platform.js"></script><script></script>
// or even better, without empty script tag:
<script src="https://apps.elfsight.com/p/platform.js"></script>
```

## Describe the bug

It doesn't cleanup script contents.
```
<script src="https://apps.elfsight.com/p/platform.js" defer></script><script>alert(1)</script>
```

## Details

It doesn't work in latest version `2.5.0`.
Pull request description: PRO-2076 no script tag bodies allowed at all when locking down to certain script sources
Limiting the src attribute has no meaning if you can put the same malicious code right in the body, so this is a security fix, not a bc break.

Closes #494 

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 247db36..9426675 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,8 @@
 # Changelog
 
+## 2.5.1 (2021-09-14):
+- The `allowedScriptHostnames` and `allowedScriptDomains` options now implicitly purge the inline content of all script tags, not just those with `src` attributes. This behavior was already strongly implied by the fact that they purged it in the case where a `src` attribute was actually present, and is necessary for the feature to provide any real security. Thanks to Grigorii Duca for pointing out the issue.
+
 ## 2.5.0 (2021-09-08):
 
 - New `allowedScriptHostnames` option, it enables you to specify which hostnames are allowed in a script tag.
diff --git a/index.js b/index.js
index c55e2cc..fa3cf6f 100644
--- a/index.js
+++ b/index.js
@@ -265,6 +265,13 @@ function sanitizeHtml(html, options, _recursing) {
         result = '';
       }
       result += '<' + name;
+
+      if (name === 'script') {
+        if (options.allowedScriptHostnames || options.allowedScriptDomains) {
+          frame.innerText = '';
+        }
+      }
+
       if (!allowedAttributesMap || has(allowedAttributesMap, name) || allowedAttributesMap['*']) {
         each(attribs, function(value, a) {
           if (!VALID_HTML_ATTRIBUTE_NAME.test(a)) {
@@ -315,10 +322,10 @@ function sanitizeHtml(html, options, _recursing) {
                 return;
               }
             }
+
             if (name === 'script' && a === 'src') {
-              let allowed = true;
 
-              frame.innerText = '';
+              let allowed = true;
 
               try {
                 const parsed = new URL(value);
diff --git a/package.json b/package.json
index e56b2ba..f6ee61a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "sanitize-html",
-  "version": "2.5.0",
+  "version": "2.5.1",
   "description": "Clean up user-submitted HTML, preserving allowlisted elements and allowlisted attributes on a per-element basis",
   "sideEffects": false,
   "main": "index.js",


Test patch:
diff --git a/test/test.js b/test/test.js
index 9312cf1..833fe5e 100644
--- a/test/test.js
+++ b/test/test.js
@@ -934,6 +934,26 @@ describe('sanitizeHtml', function() {
       allowedScriptHostnames: [ 'www.authorized.com' ]
     }), '<script src="https://www.authorized.com/lib.js"></script>');
   });
+  it('should delete the script tag content from script tags with no src when allowedScriptHostnames is present', function() {
+    assert.equal(sanitizeHtml('<script>alert("evil")</script>', {
+      allowedTags: [ 'script' ],
+      allowVulnerableTags: true,
+      allowedAttributes: {
+        script: [ 'src' ]
+      },
+      allowedScriptHostnames: [ 'www.authorized.com' ]
+    }), '<script></script>');
+  });
+  it('should delete the script tag content from script tags with no src when allowedScriptDomains is present', function() {
+    assert.equal(sanitizeHtml('<script>alert("evil")</script>', {
+      allowedTags: [ 'script' ],
+      allowVulnerableTags: true,
+      allowedAttributes: {
+        script: [ 'src' ]
+      },
+      allowedScriptDomains: [ 'www.authorized.com' ]
+    }), '<script></script>');
+  });
   it('Should allow hostnames in a script that are in allowedScriptHostnames', function() {
     assert.equal(sanitizeHtml('<script src="https://www.authorized.com/lib.js"></script>', {
       allowedTags: [ 'script' ],