Skip to content

Commit 6833f95

Browse files
committed
fix: update function to take better care of quotes as some of them are okay
1 parent 94f6b03 commit 6833f95

File tree

3 files changed

+14
-12
lines changed

3 files changed

+14
-12
lines changed

src/libs/localization-api/localization.controller.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ describe('UmbLocalizeController', () => {
177177

178178
it('should encode HTML entities', () => {
179179
expect(controller.term('withInlineToken', 'Hello', '<script>alert("XSS")</script>'), 'XSS detected').to.equal(
180-
'Hello &lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;',
180+
'Hello &lt;script&gt;alert(&#34;XSS&#34;)&lt;/script&gt;',
181181
);
182182
});
183183

src/packages/core/utils/sanitize/escape-html.function.test.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,6 @@ import { escapeHTML } from './escape-html.function.js';
33

44
describe('escapeHtml', () => {
55
it('should escape html', () => {
6-
expect(escapeHTML('<script>alert("XSS")</script>')).to.equal('&lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;');
7-
});
8-
9-
it('should escape html with single quotes', () => {
10-
expect(escapeHTML("<script>alert('XSS')</script>")).to.equal('&lt;script&gt;alert(&#39;XSS&#39;)&lt;/script&gt;');
11-
});
12-
13-
it('should escape html with mixed quotes', () => {
14-
expect(escapeHTML("<script>alert('XSS')</script>")).to.equal('&lt;script&gt;alert(&#39;XSS&#39;)&lt;/script&gt;');
6+
expect(escapeHTML('<script>alert("XSS")</script>')).to.equal('&lt;script&gt;alert(&#34;XSS&#34;)&lt;/script&gt;');
157
});
168
});

src/packages/core/utils/sanitize/escape-html.function.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
const SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
2+
// Match everything outside of normal chars and " (quote character)
3+
const NON_ALPHANUMERIC_REGEXP = /([^#-~| |!])/g;
4+
15
/**
26
* Escapes HTML entities in a string.
37
* @example escapeHTML('<script>alert("XSS")</script>'), // "&lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;"
@@ -12,8 +16,14 @@ export function escapeHTML(html: unknown): string {
1216
return html
1317
.toString()
1418
.replace(/&/g, '&amp;')
15-
.replace(/"/g, '&quot;')
16-
.replace(/'/g, '&#39;')
19+
.replace(SURROGATE_PAIR_REGEXP, function (value) {
20+
const hi = value.charCodeAt(0);
21+
const low = value.charCodeAt(1);
22+
return '&#' + ((hi - 0xd800) * 0x400 + (low - 0xdc00) + 0x10000) + ';';
23+
})
24+
.replace(NON_ALPHANUMERIC_REGEXP, function (value) {
25+
return '&#' + value.charCodeAt(0) + ';';
26+
})
1727
.replace(/</g, '&lt;')
1828
.replace(/>/g, '&gt;');
1929
}

0 commit comments

Comments
 (0)