mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-01-12 22:45:52 +08:00
fix($parse): forbid __{define,lookup}{Getter,Setter}__ properties
It was possible to use `{}.__defineGetter__.call(null, 'alert', (0).valueOf.bind(0))` to set
`window.alert` to a false-ish value, thereby breaking the `isWindow` check, which might lead
to arbitrary code execution in browsers that let you obtain the window object using Array methods.
Prevent that by blacklisting the nasty __{define,lookup}{Getter,Setter}__ properties.
BREAKING CHANGE:
This prevents the use of __{define,lookup}{Getter,Setter}__ inside angular
expressions. If you really need them for some reason, please wrap/bind them to make them
less dangerous, then make them available through the scope object.
This commit is contained in:
@@ -38,6 +38,11 @@ function ensureSafeMemberName(name, fullExpression) {
|
||||
throw $parseMinErr('isecfld',
|
||||
'Referencing "constructor" field in Angular expressions is disallowed! Expression: {0}',
|
||||
fullExpression);
|
||||
} else if (name === "__defineGetter__" || name === "__defineSetter__"
|
||||
|| name === "__lookupGetter__" || name === "__lookupSetter__") {
|
||||
throw $parseMinErr('isecgetset',
|
||||
'Defining and looking up getters and setters in Angular expressions is disallowed! '
|
||||
+'Expression: {0}', fullExpression);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
@@ -64,6 +69,11 @@ function ensureSafeObject(obj, fullExpression) {
|
||||
throw $parseMinErr('isecobj',
|
||||
'Referencing Object in Angular expressions is disallowed! Expression: {0}',
|
||||
fullExpression);
|
||||
} else if (obj === ({}).__defineGetter__ || obj === ({}).__defineSetter__
|
||||
|| obj === ({}).__lookupGetter__ || obj === ({}).__lookupSetter__) {
|
||||
throw $parseMinErr('isecgetset',
|
||||
'Defining and looking up getters and setters in Angular expressions is disallowed! '
|
||||
+'Expression: {0}', fullExpression);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
|
||||
@@ -1032,6 +1032,81 @@ describe('parser', function() {
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
describe('getters and setters', function() {
|
||||
it('should NOT allow invocation of __defineGetter__', function() {
|
||||
expect(function() {
|
||||
scope.$eval('{}.__defineGetter__("a", "".charAt)');
|
||||
}).toThrowMinErr(
|
||||
'$parse', 'isecgetset', 'Defining and looking up getters and setters in '+
|
||||
'Angular expressions is disallowed! Expression: '+
|
||||
'{}.__defineGetter__("a", "".charAt)');
|
||||
|
||||
expect(function() {
|
||||
scope.$eval('{}.__defineGetter__.call({}, "a", "".charAt)');
|
||||
}).toThrowMinErr(
|
||||
'$parse', 'isecgetset', 'Defining and looking up getters and setters in '+
|
||||
'Angular expressions is disallowed! Expression: '+
|
||||
'{}.__defineGetter__.call({}, "a", "".charAt)');
|
||||
|
||||
expect(function() {
|
||||
scope.$eval('{}["__defineGetter__"].call({}, "a", "".charAt)');
|
||||
}).toThrowMinErr(
|
||||
'$parse', 'isecgetset', 'Defining and looking up getters and setters in '+
|
||||
'Angular expressions is disallowed! Expression: '+
|
||||
'{}["__defineGetter__"].call({}, "a", "".charAt)');
|
||||
});
|
||||
|
||||
it('should NOT allow invocation of __defineSetter__', function() {
|
||||
expect(function() {
|
||||
scope.$eval('{}.__defineSetter__("a", "".charAt)');
|
||||
}).toThrowMinErr(
|
||||
'$parse', 'isecgetset', 'Defining and looking up getters and setters in '+
|
||||
'Angular expressions is disallowed! Expression: '+
|
||||
'{}.__defineSetter__("a", "".charAt)');
|
||||
|
||||
expect(function() {
|
||||
scope.$eval('{}.__defineSetter__.call({}, "a", "".charAt)');
|
||||
}).toThrowMinErr(
|
||||
'$parse', 'isecgetset', 'Defining and looking up getters and setters in '+
|
||||
'Angular expressions is disallowed! Expression: '+
|
||||
'{}.__defineSetter__.call({}, "a", "".charAt)');
|
||||
});
|
||||
|
||||
it('should NOT allow invocation of __lookupGetter__', function() {
|
||||
expect(function() {
|
||||
scope.$eval('{}.__lookupGetter__("a")');
|
||||
}).toThrowMinErr(
|
||||
'$parse', 'isecgetset', 'Defining and looking up getters and setters in '+
|
||||
'Angular expressions is disallowed! Expression: '+
|
||||
'{}.__lookupGetter__("a")');
|
||||
|
||||
expect(function() {
|
||||
scope.$eval('{}.__lookupGetter__.call({}, "a")');
|
||||
}).toThrowMinErr(
|
||||
'$parse', 'isecgetset', 'Defining and looking up getters and setters in '+
|
||||
'Angular expressions is disallowed! Expression: '+
|
||||
'{}.__lookupGetter__.call({}, "a")');
|
||||
});
|
||||
|
||||
it('should NOT allow invocation of __lookupSetter__', function() {
|
||||
expect(function() {
|
||||
scope.$eval('{}.__lookupSetter__("a")');
|
||||
}).toThrowMinErr(
|
||||
'$parse', 'isecgetset', 'Defining and looking up getters and setters in '+
|
||||
'Angular expressions is disallowed! Expression: '+
|
||||
'{}.__lookupSetter__("a")');
|
||||
|
||||
expect(function() {
|
||||
scope.$eval('{}.__lookupSetter__.call({}, "a")');
|
||||
}).toThrowMinErr(
|
||||
'$parse', 'isecgetset', 'Defining and looking up getters and setters in '+
|
||||
'Angular expressions is disallowed! Expression: '+
|
||||
'{}.__lookupSetter__.call({}, "a")');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('constant', function() {
|
||||
it('should mark scalar value expressions as constant', inject(function($parse) {
|
||||
expect($parse('12.3').constant).toBe(true);
|
||||
|
||||
Reference in New Issue
Block a user