Skip to content

Commit 24660d2

Browse files
authored
Merge pull request #81 from ecosia/mw-improve-sanitizer
Improve sanitizer
2 parents 0c3baf9 + bf395d1 commit 24660d2

File tree

3 files changed

+63
-5
lines changed

3 files changed

+63
-5
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue-safe-html",
3-
"version": "2.1.0",
3+
"version": "2.2.0",
44
"description": "A Vue directive which renders sanitised HTML dynamically",
55
"main": "dist/main.js",
66
"repository": "[email protected]:ecosia/vue-safe-html.git",

src/utils.js

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,32 @@
66
*/
77
// eslint-disable-next-line import/prefer-default-export
88
export const sanitizeHTML = (htmlString, allowedTags = []) => {
9+
// Add an optional white space to the allowed tags
10+
const allowedTagsWhiteSpaced = allowedTags.map((tag) => `${tag}\\s*`);
11+
12+
// Remove tag attributes
13+
// The solution for this was found on:
14+
// https://stackoverflow.com/questions/4885891/regex-for-removing-all-attributes-from-a-paragraph
15+
const htmlWithoutAttributes = htmlString.replace(/<(\w+)(.|[\r\n])*?>/g, '<$1>');
16+
917
const expression = (allowedTags.length > 0) ?
10-
`<(?!((?:/s*)?(?:${allowedTags.join('|')})))([^>])+>` :
11-
'<[^>]*>';
12-
const regExp = new RegExp(expression, 'g');
13-
return htmlString.replace(regExp, '');
18+
// Regex explanation
19+
// Note: \ needs to be escaped in the final expression
20+
// '<' Match the starting tag
21+
// '(' Create a matching group
22+
// '?!' Use negative lookup
23+
// we only want to match the tags that are not in the allowedTags array
24+
// '\s*?' Optional match of any white space charater before optional /
25+
// '\/?' Matches / zero to one time for the closing tag
26+
// '\s*?' Optional match of any white space charater after optional /
27+
// '(${allowedTags.join('|')})>' matching group of the allowed tags
28+
// ')' close the matching group of negative lookup
29+
// '\w*[^<>]*' matches any word that isn't in the excluded group
30+
// '>' Match closing tagq
31+
`<(?!\\s*\\/?\\s*(${allowedTagsWhiteSpaced.join('|')})>)\\w*[^<>]*>` :
32+
// Strips all tags
33+
'<(\\/?\\w*)\\w*[^<>]*>';
34+
35+
const regExp = new RegExp(expression, 'gm');
36+
return htmlWithoutAttributes.replace(regExp, '');
1437
};

src/utils.test.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,40 @@ describe('Utils', () => {
1414
const expected = 'An html<br><strong>string</strong>';
1515
expect(utils.sanitizeHTML(given, allowedTags)).toBe(expected);
1616
});
17+
18+
it('Strips input tags', () => {
19+
const allowedTags = ['strong', 'i'];
20+
const given = '<p><i>An</i> <strong>input field</strong><input type="button" /></p>';
21+
const expected = '<i>An</i> <strong>input field</strong>';
22+
expect(utils.sanitizeHTML(given, allowedTags)).toBe(expected);
23+
});
24+
25+
it('Strips similar tags', () => {
26+
const allowedTags = ['p', 'b', 's'];
27+
const given = '<sp>Test1</sp> <sssp>Test2</sssp><script></script> <blockquote>quote</blockquote>';
28+
const expected = 'Test1 Test2 quote';
29+
expect(utils.sanitizeHTML(given, allowedTags)).toBe(expected);
30+
});
31+
32+
it('Considers whitespaces', () => {
33+
const allowedTags = ['p'];
34+
const given = '<p>Test1</ p><p>Test2</ p>';
35+
const expected = '<p>Test1</ p><p>Test2</ p>';
36+
expect(utils.sanitizeHTML(given, allowedTags)).toBe(expected);
37+
});
38+
39+
it('Removes all tags with empty allowed tags', () => {
40+
const allowedTags = [];
41+
const given = '<p>Test1</p> <strong >Test2</strong> < i>Test3</i>';
42+
const expected = 'Test1 Test2 Test3';
43+
expect(utils.sanitizeHTML(given, allowedTags)).toBe(expected);
44+
});
45+
46+
it('Removes attributes from html', () => {
47+
const allowedTags = ['p'];
48+
const given = '<p data-test="test" title="test2">Test1</p> <strong data-test=\'test2\'>Test2</strong>';
49+
const expected = '<p>Test1</p> Test2';
50+
expect(utils.sanitizeHTML(given, allowedTags)).toBe(expected);
51+
});
1752
});
1853
});

0 commit comments

Comments
 (0)