Skip to content

Commit

Permalink
sanitize spread attributes and disallow invalid attribute names
Browse files Browse the repository at this point in the history
  • Loading branch information
Rich-Harris committed Aug 1, 2018
1 parent 8a89e7a commit 630bc5c
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/compile/Compiler.ts
Expand Up @@ -310,11 +310,12 @@ export default class Compiler {
: `_svelteTransitionManager`;

inlineHelpers += `\n\nvar ${this.alias(name)} = window.${global} || (window.${global} = ${code});\n\n`;
} else if (name === 'escaped' || name === 'missingComponent') {
} else if (name === 'escaped' || name === 'missingComponent' || name === 'invalidAttributeNameCharacter') {
// vars are an awkward special case... would be nice to avoid this
const alias = this.alias(name);
inlineHelpers += `\n\nconst ${alias} = ${code};`
} else {
if (!expression.id) console.log(name, expression);
const alias = this.alias(expression.id.name);
if (alias !== expression.id.name) {
code.overwrite(expression.id.start, expression.id.end, alias);
Expand Down
13 changes: 12 additions & 1 deletion src/shared/ssr.js
@@ -1,12 +1,23 @@
// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
// https://infra.spec.whatwg.org/#noncharacter
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;

export function spread(args) {
const attributes = Object.assign({}, ...args);
let str = '';

Object.keys(attributes).forEach(name => {
if (invalidAttributeNameCharacter.test(name)) return;

const value = attributes[name];
if (value === undefined) return;
if (value === true) str += " " + name;
str += " " + name + "=" + JSON.stringify(value);

const escaped = String(value)
.replace(/"/g, '&#34;')
.replace(/'/g, '&#39;');

str += " " + name + "=" + JSON.stringify(escaped);
});

return str;
Expand Down
@@ -0,0 +1,4 @@
<div
foo="&#34;></div><script>alert(42)</script>"
bar="&#39;></div><script>alert(42)</script>"
></div>
@@ -0,0 +1,16 @@
<div {...props}></div>

<script>

export default {
data() {
return {
props: {
foo: '"></div><script>alert(42)</' + 'script>',
bar: "'></div><script>alert(42)</" + 'script>',
['"></div><script>alert(42)</' + 'script>']: 'baz'
}
};
}
};
</script>

0 comments on commit 630bc5c

Please sign in to comment.