sanitize-html 1.26.0 → 1.27.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 +3 -0
- package/README.md +23 -4
- package/dist/sanitize-html-es2015.js +10 -4
- package/dist/sanitize-html.js +3 -2
- package/dist/sanitize-html.min.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
## Changelog
|
|
2
2
|
|
|
3
|
+
1.27.0:
|
|
4
|
+
- Adds the `allowedIframeDomains` option. This works similar to `allowedIframeHostnames`, where you would set it to an array of web domains. It would then permit any hostname on those domains to be used in iframe `src` attributes. Thanks to [Stanislav Kravchenko](https://github.com/StanisLove) for the contribution.
|
|
5
|
+
|
|
3
6
|
1.26.0:
|
|
4
7
|
- Adds the `option` element to the default `nonTextTagsArray` of tags with contents that aren't meant to be displayed visually as text. This can be overridden with the `nonTextTags` option.
|
|
5
8
|
|
package/README.md
CHANGED
|
@@ -344,14 +344,15 @@ Note that the text passed to the `textFilter` method is already escaped for safe
|
|
|
344
344
|
|
|
345
345
|
### Iframe Filters
|
|
346
346
|
|
|
347
|
-
If you would like to allow iframe tags but want to control the domains that are allowed through you can provide an array of hostnames that you would like to allow as iframe sources. This hostname is a property in the options object passed as an argument to the `sanitize-html` function.
|
|
347
|
+
If you would like to allow iframe tags but want to control the domains that are allowed through you can provide an array of hostnames and(or) array of domains that you would like to allow as iframe sources. This hostname is a property in the options object passed as an argument to the `sanitize-html` function.
|
|
348
348
|
|
|
349
|
-
|
|
349
|
+
These arrays will be checked against the html that is passed to the function and return only `src` urls that include the allowed hostnames or domains in the object. The url in the html that is passed must be formatted correctly (valid hostname) as an embedded iframe otherwise the module will strip out the src from the iframe.
|
|
350
350
|
|
|
351
351
|
Make sure to pass a valid hostname along with the domain you wish to allow, i.e.:
|
|
352
352
|
|
|
353
353
|
```javascript
|
|
354
|
-
allowedIframeHostnames: ['www.youtube.com', 'player.vimeo.com']
|
|
354
|
+
allowedIframeHostnames: ['www.youtube.com', 'player.vimeo.com'],
|
|
355
|
+
allowedIframeDomains: ['zoom.us']
|
|
355
356
|
```
|
|
356
357
|
|
|
357
358
|
You may also specify whether or not to allow relative URLs as iframe sources.
|
|
@@ -360,7 +361,7 @@ You may also specify whether or not to allow relative URLs as iframe sources.
|
|
|
360
361
|
allowIframeRelativeUrls: true
|
|
361
362
|
```
|
|
362
363
|
|
|
363
|
-
Note that if unspecified, relative URLs will be allowed by default if no hostname filter is provided but removed by default if a hostname filter is provided.
|
|
364
|
+
Note that if unspecified, relative URLs will be allowed by default if no hostname or domain filter is provided but removed by default if a hostname or domain filter is provided.
|
|
364
365
|
|
|
365
366
|
**Remember that the `iframe` tag must be allowed as well as the `src` attribute.**
|
|
366
367
|
|
|
@@ -411,6 +412,24 @@ clean = sanitizeHtml('<p><iframe src="https://www.vimeo/video/12345"></iframe><p
|
|
|
411
412
|
|
|
412
413
|
will return an empty iframe tag.
|
|
413
414
|
|
|
415
|
+
If you want to allow any subdomain of any level you can provide the domain in `allowedIframeDomains`
|
|
416
|
+
|
|
417
|
+
```javascript
|
|
418
|
+
clean = sanitizeHtml('<p><iframe src="https://us02web.zoom.us/embed/12345"></iframe><p>', {
|
|
419
|
+
allowedTags: [ 'p', 'em', 'strong', 'iframe' ],
|
|
420
|
+
allowedClasses: {
|
|
421
|
+
'p': [ 'fancy', 'simple' ],
|
|
422
|
+
},
|
|
423
|
+
allowedAttributes: {
|
|
424
|
+
'iframe': ['src']
|
|
425
|
+
},
|
|
426
|
+
allowedIframeHostnames: ['www.youtube.com', 'player.vimeo.com'],
|
|
427
|
+
allowedIframeDomains: ['zoom.us']
|
|
428
|
+
});
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
will pass through as safe.
|
|
432
|
+
|
|
414
433
|
### Allowed CSS Classes
|
|
415
434
|
|
|
416
435
|
If you wish to allow specific CSS classes on a particular element, you can do so with the `allowedClasses` option. Any other CSS classes are discarded.
|
|
@@ -20775,13 +20775,19 @@ function sanitizeHtml(html, options, _recursing) {
|
|
|
20775
20775
|
parsed = url.parse(value, false, true);
|
|
20776
20776
|
var isRelativeUrl = parsed && parsed.host === null && parsed.protocol === null;
|
|
20777
20777
|
if (isRelativeUrl) {
|
|
20778
|
-
// default value of allowIframeRelativeUrls is true
|
|
20778
|
+
// default value of allowIframeRelativeUrls is true
|
|
20779
|
+
// unless allowedIframeHostnames or allowedIframeDomains specified
|
|
20779
20780
|
allowed = has(options, "allowIframeRelativeUrls")
|
|
20780
|
-
? options.allowIframeRelativeUrls
|
|
20781
|
-
|
|
20782
|
-
|
|
20781
|
+
? options.allowIframeRelativeUrls
|
|
20782
|
+
: (!options.allowedIframeHostnames && !options.allowedIframeDomains);
|
|
20783
|
+
} else if (options.allowedIframeHostnames || options.allowedIframeDomains) {
|
|
20784
|
+
var allowedHostname = (options.allowedIframeHostnames || []).find(function (hostname) {
|
|
20783
20785
|
return hostname === parsed.hostname;
|
|
20784
20786
|
});
|
|
20787
|
+
var allowedDomain = (options.allowedIframeDomains || []).find(function(domain) {
|
|
20788
|
+
return parsed.hostname === domain || parsed.hostname.endsWith(`.${domain}`);
|
|
20789
|
+
});
|
|
20790
|
+
allowed = allowedHostname || allowedDomain;
|
|
20785
20791
|
}
|
|
20786
20792
|
} catch (e) {
|
|
20787
20793
|
// Unparseable iframe src
|
package/dist/sanitize-html.js
CHANGED
|
@@ -4915,8 +4915,9 @@ var passedAllowedAttributesMapCheck=false;if(!allowedAttributesMap||has(allowedA
|
|
|
4915
4915
|
var splitStrArray=value.split(' ');var _iterator11=_createForOfIteratorHelper(splitStrArray),_step2;try{for(_iterator11.s();!(_step2=_iterator11.n()).done;){var s=_step2.value;if(o.values.indexOf(s)!==-1){if(newValue===''){newValue=s;}else{newValue+=' '+s;}}}}catch(err){_iterator11.e(err);}finally{_iterator11.f();}}else if(o.values.indexOf(value)>=0){// verified an allowed value matches the entire attribute value
|
|
4916
4916
|
newValue=value;}value=newValue;}}}catch(err){_iterator10.e(err);}finally{_iterator10.f();}}if(passedAllowedAttributesMapCheck){if(options.allowedSchemesAppliedToAttributes.indexOf(a)!==-1){if(naughtyHref(name,value)){delete frame.attribs[a];return;}}if(name==='iframe'&&a==='src'){var allowed=true;try{// naughtyHref is in charge of whether protocol relative URLs
|
|
4917
4917
|
// are cool. We should just accept them
|
|
4918
|
-
parsed=url.parse(value,false,true);var isRelativeUrl=parsed&&parsed.host===null&&parsed.protocol===null;if(isRelativeUrl){// default value of allowIframeRelativeUrls is true
|
|
4919
|
-
|
|
4918
|
+
parsed=url.parse(value,false,true);var isRelativeUrl=parsed&&parsed.host===null&&parsed.protocol===null;if(isRelativeUrl){// default value of allowIframeRelativeUrls is true
|
|
4919
|
+
// unless allowedIframeHostnames or allowedIframeDomains specified
|
|
4920
|
+
allowed=has(options,"allowIframeRelativeUrls")?options.allowIframeRelativeUrls:!options.allowedIframeHostnames&&!options.allowedIframeDomains;}else if(options.allowedIframeHostnames||options.allowedIframeDomains){var allowedHostname=(options.allowedIframeHostnames||[]).find(function(hostname){return hostname===parsed.hostname;});var allowedDomain=(options.allowedIframeDomains||[]).find(function(domain){return parsed.hostname===domain||parsed.hostname.endsWith(".".concat(domain));});allowed=allowedHostname||allowedDomain;}}catch(e){// Unparseable iframe src
|
|
4920
4921
|
allowed=false;}if(!allowed){delete frame.attribs[a];return;}}if(a==='srcset'){try{parsed=srcset.parse(value);each(parsed,function(value){if(naughtyHref('srcset',value.url)){value.evil=true;}});parsed=filter(parsed,function(v){return!v.evil;});if(!parsed.length){delete frame.attribs[a];return;}else{value=srcset.stringify(filter(parsed,function(v){return!v.evil;}));frame.attribs[a]=value;}}catch(e){// Unparseable srcset
|
|
4921
4922
|
delete frame.attribs[a];return;}}if(a==='class'){value=filterClasses(value,allowedClassesMap[name]);if(!value.length){delete frame.attribs[a];return;}}if(a==='style'){try{var abstractSyntaxTree=postcss.parse(name+" {"+value+"}");var filteredAST=filterCss(abstractSyntaxTree,options.allowedStyles);value=stringifyStyleAttributes(filteredAST);if(value.length===0){delete frame.attribs[a];return;}}catch(e){delete frame.attribs[a];return;}}result+=' '+a;if(value&&value.length){result+='="'+escapeHtml(value,true)+'"';}}else{delete frame.attribs[a];}});}if(options.selfClosing.indexOf(name)!==-1){result+=" />";}else{result+=">";if(frame.innerText&&!hasText&&!options.textFilter){result+=frame.innerText;}}if(skip){result=tempResult+escapeHtml(result);tempResult='';}},ontext:function ontext(text){if(skipText){return;}var lastFrame=stack[stack.length-1];var tag;if(lastFrame){tag=lastFrame.tag;// If inner text was set by transform function then let's use it
|
|
4922
4923
|
text=lastFrame.innerText!==undefined?lastFrame.innerText:text;}if(options.disallowedTagsMode==='discard'&&(tag==='script'||tag==='style')){// htmlparser2 gives us these as-is. Escaping them ruins the content. Allowing
|