Released v3.11.4

This commit is contained in:
jos 2017-04-03 21:09:05 +02:00
parent e40a37197c
commit 42012688cb
8 changed files with 48 additions and 38 deletions

View File

@ -1,6 +1,11 @@
# History
## 2017-04-03, version 3.11.4
- Fixed a security vulnerability in the expression parser. Thanks @xfix.
## 2017-04-03, version 3.11.3
- Fixed a security vulnerability in the expression parser. Thanks @xfix.

11
dist/math.js vendored
View File

@ -6,7 +6,7 @@
* It features real and complex numbers, units, matrices, a large set of
* mathematical functions, and a flexible expression parser.
*
* @version 3.11.3
* @version 3.11.4
* @date 2017-04-03
*
* @license
@ -10812,13 +10812,12 @@ function _switch(mat){
* @return {*} Returns the property value when safe, else throws an error
*/
function getSafeProperty (object, prop) {
if (prop === 'constructor' || prop === '__proto__') {
throw new Error('Access to property "' + prop + '" is disabled');
}
// Note: checking for property names like "constructor" is not
// helpful since you can work around it.
var value = object[prop];
if (value === Function || value === Object) {
if (value === Function || value === Object || value === Function.bind) {
throw new Error('Access to "' + value.name + '" is disabled');
}
@ -48752,7 +48751,7 @@ module.exports = function scatter(a, j, w, x, u, mark, c, f, inverse, update, va
/* 507 */
/***/ (function(module, exports) {
module.exports = '3.11.3';
module.exports = '3.11.4';
// Note: This file is automatically generated when building math.js.
// Changes made in this file will be overwritten.

2
dist/math.map vendored

File diff suppressed because one or more lines are too long

20
dist/math.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -7,13 +7,12 @@
* @return {*} Returns the property value when safe, else throws an error
*/
function getSafeProperty (object, prop) {
if (prop === 'constructor' || prop === '__proto__') {
throw new Error('Access to property "' + prop + '" is disabled');
}
// Note: checking for property names like "constructor" is not
// helpful since you can work around it.
var value = object[prop];
if (value === Function || value === Object) {
if (value === Function || value === Object || value === Function.bind) {
throw new Error('Access to "' + value.name + '" is disabled');
}

View File

@ -1,3 +1,3 @@
module.exports = '3.11.3';
module.exports = '3.11.4';
// Note: This file is automatically generated when building math.js.
// Changes made in this file will be overwritten.

View File

@ -1,6 +1,6 @@
{
"name": "mathjs",
"version": "3.11.3",
"version": "3.11.4",
"description": "Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser with support for symbolic computation, comes with a large set of built-in functions and constants, and offers an integrated solution to work with different data types like numbers, big numbers, complex numbers, fractions, units, and matrices.",
"author": "Jos de Jong <wjosdejong@gmail.com> (https://github.com/josdejong)",
"contributors": [

View File

@ -7,50 +7,50 @@ describe('security', function () {
it ('should not allow calling Function via constructor', function () {
assert.throws(function () {
math.eval('[].map.constructor("console.log(\'hacked...\')")()');
}, /Error: Access to property "constructor" is disabled/);
}, /Error: Access to "Function" is disabled/);
})
it ('should not allow calling Function via call/apply', function () {
assert.throws(function () {
math.eval('[].map.constructor.call(null, "console.log(\'hacked...\')")()');
}, /Error: Access to property "constructor" is disabled/);
}, /Error: Access to "Function" is disabled/);
assert.throws(function () {
math.eval('[].map.constructor.apply(null, ["console.log(\'hacked...\')"])()');
}, /Error: Access to property "constructor" is disabled/);
}, /Error: Access to "Function" is disabled/);
})
it ('should not allow calling Function via constructor', function () {
assert.throws(function () {
math.eval('[].map.constructor("console.log(\'hacked...\')")()');
}, /Error: Access to property "constructor" is disabled/);
}, /Error: Access to "Function" is disabled/);
assert.throws(function () {
math.eval('[].map["constructor"]("console.log(\'hacked...\')")()');
}, /Error: Access to property "constructor" is disabled/);
}, /Error: Access to "Function" is disabled/);
})
it ('should not allow calling Function via a disguised constructor', function () {
assert.throws(function () {
math.eval('prop="constructor"; [].map[prop]("console.log(\'hacked...\')")()');
}, /Error: Access to property "constructor" is disabled/);
}, /Error: Access to "Function" is disabled/);
assert.throws(function () {
math.eval('[].map[concat("constr", "uctor")]("console.log(\'hacked...\')")()');
}, /Error: Access to property "constructor" is disabled/);
}, /Error: Access to "Function" is disabled/);
})
it ('should not allow calling Function via bind', function () {
assert.throws(function () {
math.eval('[].map.constructor.bind()("console.log(\'hacked...\')")()');
}, /Error: Access to property "constructor" is disabled/);
}, /Error: Access to "Function" is disabled/);
})
it ('should not allow calling Function via map/forEach', function () {
// TODO: simplify this test case, let it output console.log('hacked...')
assert.throws(function () {
math.eval('["//","a/*\\nreturn process.mainModule.require"]._data.map(cos.constructor)[1]()("child_process").execSync("ps >&2")');
}, /Error: Access to property "constructor" is disabled/);
}, /Error: Access to "Function" is disabled/);
})
it ('should not allow calling Function via Object.assign', function () {
@ -59,20 +59,20 @@ describe('security', function () {
math.eval('{}.constructor.assign(cos.constructor, {binding: cos.bind})\n' +
'{}.constructor.assign(cos.constructor, {bind: null})\n' +
'cos.constructor.binding()("console.log(\'hacked...\')")()');
}, /Error: Access to property "constructor" is disabled/);
}, /Error: Access to "Object" is disabled/);
})
it ('should not allow calling Function via imported, overridden function', function () {
assert.throws(function () {
var math2 = math.create();
math2.eval('import({matrix:cos.constructor},{override:1});x=["console.log(\'hacked...\')"];x()');
}, /Error: Access to property "constructor" is disabled/);
}, /Error: Access to "Function" is disabled/);
})
it ('should not allow calling Function via index retrieval', function () {
assert.throws(function () {
math.eval('a=["console.log(\'hacked...\')"]._data;a.isRange=true;x={subset:cos.constructor}[a];x()');
}, /Error: Access to property "constructor" is disabled/);
}, /Error: Access to "Function" is disabled/);
})
it ('should not allow calling Function via getOwnPropertyDescriptor', function () {
@ -90,13 +90,13 @@ describe('security', function () {
math.eval('O = {}.constructor\n' +
'd = O.getOwnPropertyDescriptor(O.__proto__, "constructor")\n' +
'eval("value", d)("console.log(\'hacked...\')")()');
}, /Error: Access to property "constructor" is disabled/);
}, /Error: Access to "Object" is disabled/);
})
it ('should not allow calling Function via a specially encoded constructor property name', function () {
assert.throws(function () {
math.eval('[].map["\\x63onstructor"]("console.log(\'hacked...\')")()');
}, /Error: Access to property "constructor" is disabled/);
}, /Error: Access to "Function" is disabled/);
})
it ('should not allow calling Object via a an object constructor', function () {
@ -104,7 +104,14 @@ describe('security', function () {
math.eval('{}.constructor.assign(expression.node.AssignmentNode.prototype, ' +
'{_compile: "".toString.bind("console.log(\'hacked...\')")})\n' +
'eval("a = 2")');
}, /Error: Access to property "constructor" is disabled/);
}, /Error: Access to "Object" is disabled/);
})
it ('should not allow calling Object via a __defineGetter__', function () {
assert.throws(function () {
math.eval('expression.node.AssignmentNode.prototype.__defineGetter__("_compile", ' +
'{}.valueOf.bind("".toString.bind("console.log(\'hacked...\')"))); eval("a = 2")')
}, /Error: Access to "bind" is disabled/);
})
});