diff options
Diffstat (limited to 'src/ng/parse.js')
| -rw-r--r-- | src/ng/parse.js | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/src/ng/parse.js b/src/ng/parse.js index c93d07de..ede3f24b 100644 --- a/src/ng/parse.js +++ b/src/ng/parse.js @@ -8,18 +8,23 @@ var promiseWarning; // ------------------------------ // Angular expressions are generally considered safe because these expressions only have direct // access to $scope and locals. However, one can obtain the ability to execute arbitrary JS code by -// obtaining a reference to native JS functions such as the Function constructor. +// obtaining a reference to native JS functions such as the Function constructor, thw global Window +// or Document object. In addition, many powerful functions for use by JavaScript code are +// published on scope that shouldn't be available from within an Angular expression. // // As an example, consider the following Angular expression: // // {}.toString.constructor(alert("evil JS code")) // // We want to prevent this type of access. For the sake of performance, during the lexing phase we -// disallow any "dotted" access to any member named "constructor". +// disallow any "dotted" access to any member named "constructor" or to any member whose name begins +// or ends with an underscore. The latter allows one to exclude the private / JavaScript only API +// available on the scope and controllers from the context of an Angular expression. // -// For reflective calls (a[b]) we check that the value of the lookup is not the Function constructor -// while evaluating the expression, which is a stronger but more expensive test. Since reflective -// calls are expensive anyway, this is not such a big deal compared to static dereferencing. +// For reflective calls (a[b]), we check that the value of the lookup is not the Function +// constructor, Window or DOM node while evaluating the expression, which is a stronger but more +// expensive test. Since reflective calls are expensive anyway, this is not such a big deal compared +// to static dereferencing. // // This sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits // against the expression language, but not to prevent exploits that were enabled by exposing @@ -33,12 +38,20 @@ var promiseWarning; // In general, it is not possible to access a Window object from an angular expression unless a // window or some DOM object that has a reference to window is published onto a Scope. -function ensureSafeMemberName(name, fullExpression) { - if (name === "constructor") { +function ensureSafeMemberName(name, fullExpression, allowConstructor) { + if (typeof name !== 'string' && toString.apply(name) !== "[object String]") { + return name; + } + if (name === "constructor" && !allowConstructor) { throw $parseMinErr('isecfld', 'Referencing "constructor" field in Angular expressions is disallowed! Expression: {0}', fullExpression); } + if (name.charAt(0) === '_' || name.charAt(name.length-1) === '_') { + throw $parseMinErr('isecprv', + 'Referencing private fields in Angular expressions is disallowed! Expression: {0}', + fullExpression); + } return name; } @@ -722,7 +735,10 @@ Parser.prototype = { return extend(function(self, locals) { var o = obj(self, locals), - i = indexFn(self, locals), + // In the getter, we will not block looking up "constructor" by name in order to support user defined + // constructors. However, if value looked up is the Function constructor, we will still block it in the + // ensureSafeObject call right after we look up o[i] (a few lines below.) + i = ensureSafeMemberName(indexFn(self, locals), parser.text, true /* allowConstructor */), v, p; if (!o) return undefined; @@ -738,7 +754,7 @@ Parser.prototype = { return v; }, { assign: function(self, value, locals) { - var key = indexFn(self, locals); + var key = ensureSafeMemberName(indexFn(self, locals), parser.text); // prevent overwriting of Function.constructor which would break ensureSafeObject check var safe = ensureSafeObject(obj(self, locals), parser.text); return safe[key] = value; |
