Skip to content

Commit 065d0f7

Browse files
authored
Merge pull request #1623 from sveltejs/CVE-2018-6341
Sanitize spread attributes in SSR
2 parents e1c5eba + 45c52c5 commit 065d0f7

File tree

6 files changed

+48
-2
lines changed

6 files changed

+48
-2
lines changed

src/compile/Compiler.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ export default class Compiler {
310310
: `_svelteTransitionManager`;
311311

312312
inlineHelpers += `\n\nvar ${this.alias(name)} = window.${global} || (window.${global} = ${code});\n\n`;
313-
} else if (name === 'escaped' || name === 'missingComponent') {
313+
} else if (name === 'escaped' || name === 'missingComponent' || name === 'invalidAttributeNameCharacter') {
314314
// vars are an awkward special case... would be nice to avoid this
315315
const alias = this.alias(name);
316316
inlineHelpers += `\n\nconst ${alias} = ${code};`

src/shared/ssr.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
1+
// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
2+
// https://infra.spec.whatwg.org/#noncharacter
3+
export const invalidAttributeNameCharacter = /[\s'"<\/=\u{FDD0}-\u{FDEF}\u{FFFE}\u{FFFF}\u{1FFFE}\u{1FFFF}\u{2FFFE}\u{2FFFF}\u{3FFFE}\u{3FFFF}\u{4FFFE}\u{4FFFF}\u{5FFFE}\u{5FFFF}\u{6FFFE}\u{6FFFF}\u{7FFFE}\u{7FFFF}\u{8FFFE}\u{8FFFF}\u{9FFFE}\u{9FFFF}\u{AFFFE}\u{AFFFF}\u{BFFFE}\u{BFFFF}\u{CFFFE}\u{CFFFF}\u{DFFFE}\u{DFFFF}\u{EFFFE}\u{EFFFF}\u{FFFFE}\u{FFFFF}\u{10FFFE}\u{10FFFF}]/u;
4+
15
export function spread(args) {
26
const attributes = Object.assign({}, ...args);
37
let str = '';
48

59
Object.keys(attributes).forEach(name => {
10+
if (invalidAttributeNameCharacter.test(name)) return;
11+
612
const value = attributes[name];
713
if (value === undefined) return;
814
if (value === true) str += " " + name;
9-
str += " " + name + "=" + JSON.stringify(value);
15+
16+
const escaped = String(value)
17+
.replace(/"/g, '&#34;')
18+
.replace(/'/g, '&#39;');
19+
20+
str += " " + name + "=" + JSON.stringify(escaped);
1021
});
1122

1223
return str;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<div
2+
foo="&#34;></div><script>alert(42)</script>"
3+
bar="&#39;></div><script>alert(42)</script>"
4+
></div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<div {...props}></div>
2+
3+
<script>
4+
5+
export default {
6+
data() {
7+
return {
8+
props: {
9+
foo: '"></div><script>alert(42)</' + 'script>',
10+
bar: "'></div><script>alert(42)</" + 'script>',
11+
['"></div><script>alert(42)</' + 'script>']: 'baz'
12+
}
13+
};
14+
}
15+
};
16+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div
2+
foo="&#34;></div><script>alert(42)</script>"
3+
></div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<div foo={foo}></div>
2+
3+
<script>
4+
5+
export default {
6+
data() {
7+
return {
8+
foo: '"></div><script>alert(42)</' + 'script>'
9+
};
10+
}
11+
};
12+
</script>

0 commit comments

Comments
 (0)