Skip to content

Commit

Permalink
Disallow access to prototype chain (CVE-2020-5219)
Browse files Browse the repository at this point in the history
  • Loading branch information
edi9999 committed Jan 23, 2020
1 parent 11fbbb5 commit 061addf
Show file tree
Hide file tree
Showing 10 changed files with 11,136 additions and 3,232 deletions.
13 changes: 13 additions & 0 deletions .editorconfig
@@ -0,0 +1,13 @@
root = true

[*]
end_of_line = lf
insert_final_newline = true

[*.js]
charset = utf-8
indent_style = tab

[{.travis.yml,package.json}]
indent_style = space
indent_size = 2
1 change: 0 additions & 1 deletion .eslintignore
@@ -1,2 +1 @@
node_modules
lib/parse.js
191 changes: 185 additions & 6 deletions .eslintrc
@@ -1,8 +1,187 @@
{
"extends": "peerigon/es5",
"root": true,
"env": {
"node": true,
"browser": true
}
"parserOptions" : {
"ecmaVersion": 7
},
"plugins": [],
"globals":{
"Promise": true,
"JQLite": true,
"JQLitePrototype": true,
"ArrayBuffer": true
},
"env": {
"node": true,
"browser": true,
"mocha": true
},
"rules": {
"accessor-pairs": 2,
"array-bracket-spacing": [2, "never"],
"arrow-parens": 0,
"arrow-spacing": [2, {"before": true, "after": true}],
"block-scoped-var": 2,
"block-spacing": [2, "always"],
"brace-style": 0,
"callback-return": 2,
"camelcase": [0 , {"properties": "never"}],
"comma-dangle": [0 , "always-multiline"],
"comma-spacing": [2, {"before": false, "after": true}],
"comma-style": [2, "last"],
"complexity": [2, 10],
"computed-property-spacing": [2, "never"],
"consistent-return": 0,
"consistent-this": [2, "self"],
"constructor-super": 2,
"curly": [2, "all"],
"default-case": 0,
"dot-location": [2, "property"],
"dot-notation": 2,
"eol-last": 2,
"eqeqeq": [2, "smart"],
"func-names": 0,
"func-style": [2, "declaration"],
"generator-star-spacing": [2, {"before": false, "after": true}],
"global-require": 0,
"guard-for-in": 2,
"handle-callback-err": 2,
"id-length": 0,
"id-match": 0,
"init-declarations": 0,
"key-spacing": [2, {"beforeColon": false, "afterColon": true, "mode": "strict"}],
"linebreak-style": 0,
"lines-around-comment": 0,
"max-nested-callbacks": 0,
"new-cap": [2, {
"newIsCapExceptions": ["Boom.badRequest", "Boom.forbidden", "Boom.unauthorized", "Boom.wrap"],
"capIsNewExceptions": ["squeeze.Squeeze"]
}],
"new-parens": 2,
"newline-after-var": 0,
"no-alert": 2,
"no-array-constructor": 2,
"no-caller": 2,
"no-catch-shadow": 0,
"no-class-assign": 2,
"no-console": 2,
"no-const-assign": 2,
"no-constant-condition": [2, {"checkLoops": false}],
"no-continue": 0,
"no-control-regex": 0,
"no-debugger": 2,
"no-delete-var": 2,
"no-div-regex": 2,
"no-dupe-args": 2,
"no-dupe-class-members": 2,
"no-dupe-keys": 2,
"no-duplicate-case": 2,
"no-else-return": 2,
"no-empty": 2,
"no-empty-character-class": 2,
"no-eval": 2,
"no-ex-assign": 2,
"no-extend-native": 2,
"no-extra-bind": 2,
"no-extra-boolean-cast": 2,
"no-extra-parens": [2, "functions"],
"no-extra-semi": 2,
"no-fallthrough": 2,
"no-floating-decimal": 2,
"no-func-assign": 2,
"no-implicit-coercion": 0,
"no-implied-eval": 2,
"no-inline-comments": 0,
"no-inner-declarations": 2,
"no-invalid-regexp": 2,
"no-irregular-whitespace": 2,
"no-iterator": 2,
"no-label-var": 2,
"no-labels": 0,
"no-lone-blocks": 2,
"no-lonely-if": 2,
"no-loop-func": 2,
"no-mixed-requires": 2,
"no-mixed-spaces-and-tabs": 0,
"no-multi-spaces": 2,
"no-multi-str": 2,
"no-multiple-empty-lines": [2, {"max": 1}],
"no-native-reassign": 2,
"no-negated-in-lhs": 2,
"no-new": 2,
"no-new-func": 2,
"no-new-object": 2,
"no-new-require": 2,
"no-new-wrappers": 2,
"no-obj-calls": 2,
"no-octal": 2,
"no-octal-escape": 2,
"no-param-reassign": 0,
"no-path-concat": 2,
"no-process-env": 2,
"no-process-exit": 2,
"no-proto": 2,
"no-redeclare": 2,
"no-regex-spaces": 2,
"no-restricted-modules": 0,
"no-restricted-syntax": 0,
"no-return-assign": 0,
"no-script-url": 2,
"no-self-compare": 2,
"no-sequences": 2,
"no-shadow": 0,
"no-shadow-restricted-names": 2,
"no-spaced-func": 2,
"no-sparse-arrays": 2,
"no-ternary": 0,
"no-this-before-super": 2,
"no-throw-literal": 2,
"no-trailing-spaces": 2,
"no-undef": 2,
"no-undef-init": 0,
"no-undefined": 0,
"no-underscore-dangle": 0,
"no-unexpected-multiline": 2,
"no-unneeded-ternary": 2,
"no-unreachable": 2,
"no-unused-expressions": 2,
"no-unused-vars": 2,
"no-use-before-define": [2, "nofunc"],
"no-useless-call": 2,
"no-useless-concat": 2,
"no-var": 0,
"no-void": 2,
"no-warning-comments": [2, {"terms": ["todo", "fixme"], "location": "anywhere"}],
"no-with": 2,
"object-curly-spacing": 0,
"object-shorthand": 0,
"one-var": 0,
"operator-assignment": [0, "always"],
"operator-linebreak": 0,
"padded-blocks": [2, "never"],
"prefer-arrow-callback": 0,
"prefer-const": 0,
"prefer-destructuring": [0, {
"AssignmentExpression": {
"array": true,
"object": false
}
}],
"prefer-reflect": 0,
"prefer-spread": 0,
"prefer-template": 0,
"quotes": [2, "double", {"avoidEscape":true}],
"quote-props": [2, "as-needed"],
"radix": 2,
"require-jsdoc": 0,
"require-yield": 2,
"semi": [2, "always"],
"semi-spacing": [2, {"before": false, "after": true}],
"sort-vars": 0,
"use-isnan": 2,
"valid-jsdoc": 0,
"valid-typeof": 2,
"vars-on-top": 0,
"wrap-iife": [2, "inside"],
"wrap-regex": 0,
"yoda": [2, "never"]
}
}
62 changes: 27 additions & 35 deletions README.md
@@ -1,5 +1,6 @@
angular-expressions
===================
**A security vulnerability has been found that affects all versions before 1.0.1. Please read this advisory https://github.com/peerigon/angular-expressions/security/advisories/GHSA-hxhm-96pp-2m43 for more information.**

# angular-expressions

**[angular's nicest part](https://github.com/angular/angular.js/blob/6b049c74ccc9ee19688bb9bbe504c300e61776dc/src/ng/parse.js) extracted as a standalone module for the browser and node.**

Expand Down Expand Up @@ -38,16 +39,13 @@ Check out [their readme](http://docs.angularjs.org/guide/expression) for further

<br />

Setup
-----
## Setup

[![npm status](https://nodei.co/npm/angular-expressions.svg?downloads=true&stars=true&downloadRank=true)](https://npmjs.org/package/angular-expressions)


<br />

Filters
-------
## Filters

Angular provides a mechanism to define filters on expressions:

Expand All @@ -62,25 +60,24 @@ Arguments are evaluated against the scope:

```javascript
expressions.filters.currency = (input, currency, digits) => {
input = input.toFixed(digits);
input = input.toFixed(digits);

if (currency === "EUR") {
return input + "";
} else {
return input + "$";
}
if (currency === "EUR") {
return input + "";
} else {
return input + "$";
}
};

expr = expressions.compile("1.2345 | currency:selectedCurrency:2");
expr({
selectedCurrency: "EUR"
selectedCurrency: "EUR"
}); // returns '1.23€'
```

<br />

API
----
## API

### exports

Expand All @@ -104,9 +101,9 @@ Example output of: `compile("tmp + 1").ast`
constant: false }
```

*NOTE* angular $parse do not export ast variable it's done by this library.
_NOTE_ angular \$parse do not export ast variable it's done by this library.

#### .compile.cache = {}
#### .compile.cache = Object.create(null)

A cache containing all compiled functions. The src is used as key. Set this on `false` to disable the cache.

Expand All @@ -122,34 +119,34 @@ The internal [Lexer](https://github.com/angular/angular.js/blob/6b049c74ccc9ee19

The internal [Parser](https://github.com/angular/angular.js/blob/6b049c74ccc9ee19688bb9bbe504c300e61776dc/src/ng/parse.js#L390).

----
---

### evaluate(scope?): *
### evaluate(scope?): \*

Evaluates the compiled `src` and returns the result of the expression. Property look-ups or assignments are executed on a given `scope`.

### evaluate.assign(scope, value): *
### evaluate.assign(scope, value): \*

Tries to assign the given `value` to the result of the compiled expression on the given `scope` and returns the result of the assignment.

<br />

In the browser
--------------
## In the browser

There is no `dist` build because it's not 2005 anymore. Use a module bundler like [webpack](http://webpack.github.io/) or [browserify](http://browserify.org/). They're both capable of CommonJS and AMD.

<br />

Security
--------
## Security

The code of angular was not secured from reading prototype, and since version 1.0.1 of angular-expressions, the module disallows reading properties that are not ownProperties. See [this blog post](http://blog.angularjs.org/2016/09/angular-16-expression-sandbox-removal.html) for more details about the sandbox that got removed completely in angular 1.6.

Comment from `angular.js/src/ng/parse.js`:

---

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
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.

As an example, consider the following Angular expression:
Expand Down Expand Up @@ -180,16 +177,13 @@ window or some DOM object that has a reference to window is published onto a Sco

<br />

## Authorship

Authorship
----------
Kudos go entirely to the great angular.js team, it's their implementation!


<br />

Contributing
------------
## Contributing

Suggestions and bug-fixes are always appreciated. Don't hesitate to create an issue or pull-request. All contributed code should pass

Expand All @@ -198,12 +192,10 @@ Suggestions and bug-fixes are always appreciated. Don't hesitate to create an is

<br />

License
-------
## License

[Unlicense](http://unlicense.org/)

Sponsors
-------
## Sponsors

[<img src="https://assets.peerigon.com/peerigon/logo/peerigon-logo-flat-spinat.png" width="150" />](https://peerigon.com)

0 comments on commit 061addf

Please sign in to comment.