Skip to content

Commit

Permalink
Fixed a security issue in typed-function allowing arbitrary code ex…
Browse files Browse the repository at this point in the history
…ecution
  • Loading branch information
josdejong committed Nov 18, 2017
1 parent 4a93787 commit 8d2d48d
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 2 deletions.
3 changes: 3 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
## not yet released, version 3.17.0

- Improved `simplify` for nested exponentiations. Thanks @IvanVergiliev.
- Fixed a security issue in `typed-function` allowing arbitrary code execution
in the JavaScript engine by creating a typed function with JavaScript code
in the name. Thanks Masato Kinugawa.


## 2017-10-18, version 3.16.5
Expand Down
2 changes: 1 addition & 1 deletion lib/expression/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ function factory (type, config, load, typed) {
value = parseAssignment();
return new AssignmentNode(node.object, node.index, value);
}
else if (type.isFunctionNode(node)) {
else if (type.isFunctionNode(node) && type.isSymbolNode(node.fn)) {
// parse function assignment like 'f(x) = x^2'
valid = true;
args = [];
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
"javascript-natural-sort": "0.7.1",
"seed-random": "2.2.0",
"tiny-emitter": "2.0.0",
"typed-function": "0.10.5"
"typed-function": "0.10.6"
},
"devDependencies": {
"benchmark": "2.1.4",
Expand Down
7 changes: 7 additions & 0 deletions test/expression/parse.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,13 @@ describe('parse', function() {
assert.equal(obj.f(2), 4);
});

it('should not parse a function assignment in an accessor node', function () {
assert.throws(function () {
var scope = {}
var obj = parseAndEval('a["b"](x)=x^2', scope);
}, /SyntaxError: Invalid left hand side of assignment operator =/)
});

it('should parse an object containing a variable assignment', function () {
var scope = {};
assert.deepEqual(parseAndEval('{f: a=42}', scope), {f: 42});
Expand Down
18 changes: 18 additions & 0 deletions test/expression/security.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,24 @@ describe('security', function () {
}, /Undefined symbol Chain/);
})

it ('should not allow passing a function name containg bad contents', function () {
// underlying issues where:
// the input '[]["fn"]()=0'
// - defines a function in the root scope, but this shouldn't be allowed syntax
// - there is a typed function created which unsecurely evaluates JS code with the function name in it
// -> when the function name contains JS code it can be executed, example:
//
// var fn = typed("(){}+console.log(`hacked...`);function a", { "": function () { } })

assert.throws(function () {
math.eval('[]["(){}+console.log(`hacked...`);function a"]()=0')
}, /SyntaxError: Invalid left hand side of assignment operator =/);

assert.throws(function () {
math.eval('{}["(){}+console.log(`hacked...`);function a"]()=0')
}, /SyntaxError: Invalid left hand side of assignment operator =/);
})

it ('should allow calling functions on math', function () {
assert.equal(math.eval('sqrt(4)'), 2);
})
Expand Down

0 comments on commit 8d2d48d

Please sign in to comment.