CVE-2017-1001002 (published 2017-11-27T14:29Z)

math.js before 3.17.0 had an arbitrary code execution in the JavaScript engine. Creating a typed function with JavaScript code in the name could result arbitrary execution.

Severity: HIGH
CVSS v2 base score: 7.5 (AV:N/AC:L/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 9.8, CRITICAL (CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-94
cwe_name: Improper Control of Generation of Code ('Code Injection')
description: The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
extended_description: 
            When a product allows a user's input to contain code syntax, it might be possible for an attacker to craft the code in such a way that it will alter the intended control flow of the product. Such an alteration could lead to arbitrary code execution.
            Injection problems encompass a wide variety of issues -- all mitigated in very different ways. For this reason, the most effective way to discuss these weaknesses is to note the distinct features which classify them as injection weaknesses. The most important issue to note is that all injection problems share one thing in common -- i.e., they allow for the injection of control plane data into the user-controlled data plane. This means that the execution of the process may be altered by sending code in through legitimate data channels, using no other mechanism. While buffer overflows, and many other flaws, involve the use of some further issue to gain execution, injection problems need only for the data to be parsed. The most classic instantiations of this category of weakness are SQL injection and format string vulnerabilities.
         
         

Fix information:
repo_url: https://github.com/josdejong/mathjs
commit_details: repo_url: https://github.com/josdejong/mathjs
author: jos
author_date: 2017-11-18 19:39:30+01:00
msg: Fixed a security issue in `typed-function` allowing arbitrary code execution
repository: repo_url: https://github.com/josdejong/mathjs
repo_name: josdejong/mathjs
description: An extensive math library for JavaScript and Node.js
repo_language: JavaScript
owner: josdejong
file_changes: filename: HISTORY.md
change_type: ModificationType.MODIFY
diff: @@ -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

programming_language: Markdown
filename: parse.js
change_type: ModificationType.MODIFY
diff: @@ -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 = [];

programming_language: JavaScript
filename: package.json
change_type: ModificationType.MODIFY
diff: @@ -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",

programming_language: Markdown
filename: parse.test.js
change_type: ModificationType.MODIFY
diff: @@ -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});

programming_language: JavaScript
filename: security.test.js
change_type: ModificationType.MODIFY
diff: @@ -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);
   })

programming_language: JavaScript