sanitize-html 1.18.1 → 1.18.5
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/.travis.yml +5 -0
- package/README.md +34 -8
- package/dist/index.js +6 -8
- package/dist/sanitize-html.js +7 -9
- package/dist/sanitize-html.min.js +8 -8
- package/package.json +1 -1
- package/src/index.js +8 -8
- package/test/test.js +41 -2
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -4,7 +4,7 @@ var quoteRegexp = require('lodash.escaperegexp');
|
|
|
4
4
|
var cloneDeep = require('lodash.clonedeep');
|
|
5
5
|
var mergeWith = require('lodash.mergewith');
|
|
6
6
|
var isString = require('lodash.isstring');
|
|
7
|
-
var isPlainObject = require('lodash.
|
|
7
|
+
var isPlainObject = require('lodash.isplainobject');
|
|
8
8
|
var srcset = require('srcset');
|
|
9
9
|
var postcss = require('postcss');
|
|
10
10
|
var url = require('url');
|
|
@@ -240,13 +240,10 @@ function sanitizeHtml(html, options, _recursing) {
|
|
|
240
240
|
}
|
|
241
241
|
}
|
|
242
242
|
if (name === 'iframe' && a === 'src') {
|
|
243
|
-
//Check if value contains proper hostname prefix
|
|
244
|
-
if (value.substring(0, 2) === '//') {
|
|
245
|
-
var prefix = 'https:';
|
|
246
|
-
value = prefix.concat(value);
|
|
247
|
-
}
|
|
248
243
|
try {
|
|
249
|
-
|
|
244
|
+
// naughtyHref is in charge of whether protocol relative URLs
|
|
245
|
+
// are cool. We should just accept them
|
|
246
|
+
parsed = url.parse(value, false, true);
|
|
250
247
|
if (options.allowedIframeHostnames) {
|
|
251
248
|
var whitelistedHostnames = options.allowedIframeHostnames.find(function(hostname) {
|
|
252
249
|
return hostname === parsed.hostname;
|
|
@@ -414,7 +411,10 @@ function sanitizeHtml(html, options, _recursing) {
|
|
|
414
411
|
if (typeof(s) !== 'string') {
|
|
415
412
|
s = s + '';
|
|
416
413
|
}
|
|
417
|
-
return s.replace(
|
|
414
|
+
return s.replace(/&(?![a-zA-Z0-9#]{1,7};)/g, '&') // Match ampersands not part of existing HTML entity
|
|
415
|
+
.replace(/</g, '<')
|
|
416
|
+
.replace(/\>/g, '>')
|
|
417
|
+
.replace(/\"/g, '"');
|
|
418
418
|
}
|
|
419
419
|
|
|
420
420
|
function naughtyHref(name, href) {
|
package/test/test.js
CHANGED
|
@@ -647,7 +647,7 @@ describe('sanitizeHtml', function() {
|
|
|
647
647
|
}), '<span style="color:yellow;text-align:center;font-family:helvetica;"></span>'
|
|
648
648
|
);
|
|
649
649
|
});
|
|
650
|
-
it('Should allow
|
|
650
|
+
it('Should allow hostnames in an iframe that are whitelisted', function() {
|
|
651
651
|
assert.equal(
|
|
652
652
|
sanitizeHtml('<iframe src="https://www.youtube.com/embed/c2IlcS7AHxM"></iframe>', {
|
|
653
653
|
allowedTags: ['p', 'iframe', 'a', 'img', 'i'],
|
|
@@ -667,7 +667,7 @@ describe('sanitizeHtml', function() {
|
|
|
667
667
|
});
|
|
668
668
|
it('Should not allow iframe urls that do not have proper hostname', function() {
|
|
669
669
|
assert.equal(
|
|
670
|
-
sanitizeHtml('<iframe src="
|
|
670
|
+
sanitizeHtml('<iframe src="https://www.vimeo.com/embed/c2IlcS7AHxM"></iframe>', {
|
|
671
671
|
allowedTags: ['p', 'iframe', 'a', 'img', 'i'],
|
|
672
672
|
allowedAttributes: {'iframe': ['src', 'href'], 'a': ['src', 'href'], 'img': ['src']},
|
|
673
673
|
allowedIframeHostnames: ['www.youtube.com', 'player.vimeo.com']
|
|
@@ -682,6 +682,32 @@ describe('sanitizeHtml', function() {
|
|
|
682
682
|
}), '<iframe src="https://www.vimeo.com/embed/c2IlcS7AHxM"></iframe>'
|
|
683
683
|
);
|
|
684
684
|
});
|
|
685
|
+
it('Should allow relative URLs for iframes', function() {
|
|
686
|
+
assert.equal(
|
|
687
|
+
sanitizeHtml('<iframe src="/foo"></iframe>', {
|
|
688
|
+
allowedTags: ['p', 'iframe', 'a', 'img', 'i'],
|
|
689
|
+
allowedAttributes: {'iframe': ['src', 'href'], 'a': ['src', 'href'], 'img': ['src']}
|
|
690
|
+
}), '<iframe src="/foo"></iframe>'
|
|
691
|
+
);
|
|
692
|
+
});
|
|
693
|
+
it('Should allow protocol-relative URLs for the right domain for iframes', function() {
|
|
694
|
+
assert.equal(
|
|
695
|
+
sanitizeHtml('<iframe src="//www.youtube.com/embed/c2IlcS7AHxM"></iframe>', {
|
|
696
|
+
allowedTags: ['p', 'iframe', 'a', 'img', 'i'],
|
|
697
|
+
allowedAttributes: {'iframe': ['src', 'href'], 'a': ['src', 'href'], 'img': ['src']},
|
|
698
|
+
allowedIframeHostnames: ['www.youtube.com', 'player.vimeo.com']
|
|
699
|
+
}), '<iframe src="//www.youtube.com/embed/c2IlcS7AHxM"></iframe>'
|
|
700
|
+
);
|
|
701
|
+
});
|
|
702
|
+
it('Should not allow protocol-relative iframe urls that do not have proper hostname', function() {
|
|
703
|
+
assert.equal(
|
|
704
|
+
sanitizeHtml('<iframe src="//www.vimeo.com/embed/c2IlcS7AHxM"></iframe>', {
|
|
705
|
+
allowedTags: ['p', 'iframe', 'a', 'img', 'i'],
|
|
706
|
+
allowedAttributes: {'iframe': ['src', 'href'], 'a': ['src', 'href'], 'img': ['src']},
|
|
707
|
+
allowedIframeHostnames: ['www.youtube.com', 'player.vimeo.com']
|
|
708
|
+
}), '<iframe></iframe>'
|
|
709
|
+
);
|
|
710
|
+
});
|
|
685
711
|
it('Should only allow attributes to have any combination of specific values', function() {
|
|
686
712
|
assert.equal(
|
|
687
713
|
sanitizeHtml('<iframe name=\"IFRAME\" allowfullscreen=\"true\" sandbox=\"allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts allow-top-navigation\"></iframe>',{
|
|
@@ -722,4 +748,17 @@ describe('sanitizeHtml', function() {
|
|
|
722
748
|
allowedSchemes: sanitizeHtml.defaults.allowedSchemes.concat([ 'tel' ]),
|
|
723
749
|
}), '<q cite=\"http://www.google.com\">HTTP</q><q cite=\"https://www.google.com\">HTTPS</q><q cite=\"mailto://www.google.com\">MAILTO</q><q cite=\"tel://www.google.com\">TEL</q><q cite=\"ftp://www.google.com\">FTP</q><q>DATA</q><q>LDAP</q><q>ACROBAT</q><q>VBSCRIPT</q><q>FILE</q><q>RLOGIN</q><q>WEBCAL</q><q>JAVASCRIPT</q><q>MMS</q>');
|
|
724
750
|
});
|
|
751
|
+
it('Should encode &, <, > and "', function() {
|
|
752
|
+
assert.equal(sanitizeHtml('"< & >"'), '"< & >"');
|
|
753
|
+
});
|
|
754
|
+
it('Should not double encode ampersands on HTML entities', function() {
|
|
755
|
+
var textIn = 'This & & that ® 
 ± OK?';
|
|
756
|
+
var expectedResult = 'This & & that ® 
 ± OK?';
|
|
757
|
+
var sanitizeHtmlOptions = {
|
|
758
|
+
parser: {
|
|
759
|
+
decodeEntities: false
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
assert.equal(sanitizeHtml(textIn, sanitizeHtmlOptions), expectedResult);
|
|
763
|
+
});
|
|
725
764
|
});
|