Skip to content

Commit 0bee5a0

Browse files
committed
better xss mitigation
1 parent a891df2 commit 0bee5a0

File tree

2 files changed

+33
-17
lines changed

2 files changed

+33
-17
lines changed

src/exp-parser.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
var utils = require('./utils'),
2-
stringSaveRE = /"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g,
1+
var utils = require('./utils'),
2+
stringSaveRE = /"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g,
33
stringRestoreRE = /"(\d+)"/g,
4-
constructorRE = /(^|\.)constructor\(/
4+
constructorRE = new RegExp('constructor'.split('').join('[\'"+, ]*')),
5+
unicodeRE = /\\u\d\d\d\d/
56

67
// Variable extraction scooped from https://github.com/RubyLouvre/avalon
78

@@ -110,7 +111,8 @@ module.exports = {
110111
* created as bindings.
111112
*/
112113
parse: function (exp, compiler) {
113-
if (constructorRE.test(exp)) {
114+
// unicode and 'constructor' are not allowed for XSS security.
115+
if (unicodeRE.test(exp) || constructorRE.test(exp)) {
114116
utils.warn('Unsafe expression: ' + exp)
115117
return function () {}
116118
}

test/unit/specs/exp-parser.js

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -112,20 +112,34 @@ describe('UNIT: Expression Parser', function () {
112112

113113
})
114114

115-
describe('Basic XSS protection', function () {
115+
describe('XSS protection', function () {
116116

117-
var cases = [{
118-
xss: true,
119-
exp: "constructor.constructor('alert(1)')()",
120-
vm: {},
121-
expectedValue: undefined
122-
},
123-
{
124-
xss: true,
125-
exp: "\"\".toString.constructor.constructor('alert(1)')()",
126-
vm: {},
127-
expectedValue: undefined
128-
}]
117+
var cases = [
118+
{
119+
xss: true,
120+
exp: "constructor.constructor('alert(1)')()",
121+
vm: {},
122+
expectedValue: undefined
123+
},
124+
{
125+
xss: true,
126+
exp: "\"\".toString.constructor.constructor('alert(1)')()",
127+
vm: {},
128+
expectedValue: undefined
129+
},
130+
{
131+
xss: true,
132+
exp: "\"\".toString['cons' + 'tructor']['cons' + 'tructor']('alert(1)')()",
133+
vm: {},
134+
expectedValue: undefined
135+
},
136+
{
137+
xss: true,
138+
exp: "\"\".toString['\\u0063ons' + 'tructor']['\\u0063ons' + 'tructor']('alert(1)')()",
139+
vm: {},
140+
expectedValue: undefined
141+
}
142+
]
129143

130144
cases.forEach(describeCase)
131145

0 commit comments

Comments
 (0)