diff --git a/src/ng/parse.js b/src/ng/parse.js index 536965301..626b78d66 100644 --- a/src/ng/parse.js +++ b/src/ng/parse.js @@ -43,6 +43,9 @@ function ensureSafeMemberName(name, fullExpression) { throw $parseMinErr('isecgetset', 'Defining and looking up getters and setters in Angular expressions is disallowed! ' +'Expression: {0}', fullExpression); + } else if (name === "__proto__") { + throw $parseMinErr('isecproto', 'Using __proto__ in Angular expressions is disallowed! ' + +'Expression: {0}', fullExpression); } return name; } @@ -713,6 +716,10 @@ Parser.prototype = { i = indexFn(self, locals), v, p; + if (i === "__proto__") { + throw $parseMinErr('isecproto', 'Using __proto__ in Angular expressions is disallowed! ' + +'Expression: {0}', parser.text); + } if (!o) return undefined; v = ensureSafeObject(o[i], parser.text); if (v && v.then && parser.options.unwrapPromises) { diff --git a/test/ng/parseSpec.js b/test/ng/parseSpec.js index 61d7af3ff..a0aeae799 100644 --- a/test/ng/parseSpec.js +++ b/test/ng/parseSpec.js @@ -1106,6 +1106,22 @@ describe('parser', function() { }); }); + + describe('__proto__', function() { + it('should NOT allow access to __proto__', function() { + expect(function() { + scope.$eval('{}.__proto__.foo = 1'); + }).toThrowMinErr( + '$parse', 'isecproto', 'Using __proto__ in Angular expressions is disallowed!'+ + ' Expression: {}.__proto__.foo = 1'); + expect(function() { + scope.$eval('{}["__pro"+"to__"].foo = 1'); + }).toThrowMinErr( + '$parse', 'isecproto', 'Using __proto__ in Angular expressions is disallowed!'+ + ' Expression: {}["__pro"+"to__"].foo = 1'); + }); + }); + describe('constant', function() { it('should mark scalar value expressions as constant', inject(function($parse) {