Skip to content

Commit

Permalink
fix: escape unsafe key chars (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 authored Apr 14, 2019
1 parent 650239d commit ecde7cf
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
13 changes: 11 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const consola = require('consola')
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$';
const unsafeChars = /[<>\b\f\n\r\t\0\u2028\u2029]/g;
const reserved = /^(?:do|if|in|for|int|let|new|try|var|byte|case|char|else|enum|goto|long|this|void|with|await|break|catch|class|const|final|float|short|super|throw|while|yield|delete|double|export|import|native|return|switch|throws|typeof|boolean|default|extends|finally|package|private|abstract|continue|debugger|function|volatile|interface|protected|transient|implements|instanceof|synchronized)$/;
const escaped: Record<string, string> = {
'<': '\\u003C',
Expand Down Expand Up @@ -246,12 +247,20 @@ function getType(thing: any) {
return Object.prototype.toString.call(thing).slice(8, -1);
}

function escapeUnsafeChar(c: string) {
return escaped[c] || c
}

function escapeUnsafeChars(str: string) {
return str.replace(unsafeChars, escapeUnsafeChar)
}

function safeKey(key: string) {
return /^[_$a-zA-Z][_$a-zA-Z0-9]*$/.test(key) ? key : JSON.stringify(key);
return /^[_$a-zA-Z][_$a-zA-Z0-9]*$/.test(key) ? key : escapeUnsafeChars(JSON.stringify((key)));
}

function safeProp(key: string) {
return /^[_$a-zA-Z][_$a-zA-Z0-9]*$/.test(key) ? `.${key}` : `[${JSON.stringify(key)}]`;
return /^[_$a-zA-Z][_$a-zA-Z0-9]*$/.test(key) ? `.${key}` : `[${escapeUnsafeChars(JSON.stringify(key))}]`;
}

function stringifyString(str: string) {
Expand Down
6 changes: 5 additions & 1 deletion test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,11 @@ describe('devalue', () => {
new toJSONTest(`"</script><script src='https://evil.com/script.js'>alert('pwned')</script><script>"`),
`"\\u003C\\u002Fscript\\u003E\\u003Cscript src='https:\\u002F\\u002Fevil.com\\u002Fscript.js'\\u003Ealert('pwned')\\u003C\\u002Fscript\\u003E\\u003Cscript\\u003E"`
);

test(
'Dangerous key',
{ '<svg onload=alert("xss_works")>': 'bar' },
'{"\\u003Csvg onload=alert(\\"xss_works\\")\\u003E":"bar"}'
)
});

describe('misc', () => {
Expand Down

0 comments on commit ecde7cf

Please sign in to comment.