[fix] harden attribute escaping during ssr (#7530)

pull/7641/head
Maurício Kishi 2 years ago committed by GitHub
parent 9635a2e413
commit f8605d6acb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -85,18 +85,20 @@ export function escape(value: unknown, is_attr = false) {
let escaped = '';
let last = 0;
while (pattern.test(str)) {
const i = pattern.lastIndex - 1;
const ch = str[i];
escaped += str.substring(last, i) + (ch === '&' ? '&' : (ch === '"' ? '"' : '<'));
last = i + 1;
}
while (pattern.test(str)) {
const i = pattern.lastIndex - 1;
const ch = str[i];
escaped += str.substring(last, i) + (ch === '&' ? '&' : (ch === '"' ? '"' : '<'));
last = i + 1;
}
return escaped + str.substring(last);
}
export function escape_attribute_value(value) {
return typeof value === 'string' ? escape(value, true) : value;
// keep booleans, null, and undefined for the sake of `spread`
const should_escape = typeof value === 'string' || (value && typeof value === 'object');
return should_escape ? escape(value, true) : value;
}
export function escape_object(obj) {
@ -192,7 +194,7 @@ export function create_ssr_component(fn) {
export function add_attribute(name, value, boolean) {
if (value == null || (boolean && !value)) return '';
const assignment = (boolean && value === true) ? '' : `="${escape_attribute_value(value.toString())}"`;
const assignment = (boolean && value === true) ? '' : `="${escape(value, true)}"`;
return ` ${name}${assignment}`;
}

@ -2,4 +2,10 @@
bar="'></div><script>alert(42)</script>"
foo="&quot;></div><script>alert(42)</script>"
qux="&amp;&amp;&amp;"
></div>
quux="&quot;><script>alert(42)</script>"
></div>
<div
foo="foo"
unsafe="&quot;><script>alert(42)</script>"
></div>

@ -1,10 +1,15 @@
<script>
const safe = { foo: 'foo' };
const unsafe = { toString: () => '"><script>alert(42)<\/script>' };
export let props = {
foo: '"></div><script>alert(42)</' + 'script>',
bar: "'></div><script>alert(42)</" + 'script>',
['"></div><script>alert(42)</' + 'script>']: 'baz',
qux: '&&&',
quux: unsafe
};
</script>
<div {...props}></div>
<div {...props}></div>
<div {...safe} {unsafe}></div>

Loading…
Cancel
Save