Skip to content

Commit

Permalink
Fix object pollution vulnerability in math.config
Browse files Browse the repository at this point in the history
  • Loading branch information
josdejong committed Oct 10, 2020
1 parent a2858e2 commit ecb8051
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 1 deletion.
5 changes: 5 additions & 0 deletions HISTORY.md
@@ -1,5 +1,10 @@
# History

# not yet published, version 7.5.1

- Fix object pollution vulnerability in `math.config`. Thanks Snyk.


# 2020-10-07, version 7.5.0

- Function `pickRandom` now allows randomly picking elements from matrices
Expand Down
4 changes: 3 additions & 1 deletion src/utils/object.js
Expand Up @@ -86,7 +86,9 @@ export function deepExtend (a, b) {
}

for (const prop in b) {
if (hasOwnProperty(b, prop)) {
// We check against prop not being in Object.prototype or Function.prototype
// to prevent polluting for example Object.__proto__.
if (hasOwnProperty(b, prop) && !(prop in Object.prototype) && !(prop in Function.prototype)) {
if (b[prop] && b[prop].constructor === Object) {
if (a[prop] === undefined) {
a[prop] = {}
Expand Down
28 changes: 28 additions & 0 deletions test/unit-tests/expression/security.test.js
Expand Up @@ -390,6 +390,34 @@ describe('security', function () {
assert.strictEqual(math.expression.mathWithTransform.chain, undefined)
assert.deepStrictEqual(math.evaluate('chain'), math.unit('chain'))
})

it('should not allow polluting the Object prototype via config', () => {
const obj = {}
assert.strictEqual(obj.polluted, undefined)

// change the configuration
const newConfig = JSON.parse('{"__proto__":{"polluted":"yes"}}')
math.config(newConfig)
assert.strictEqual(obj.polluted, undefined)
})

it('should not allow polluting the Object prototype via config via the expression parser', () => {
const obj = {}
assert.strictEqual(obj.polluted, undefined)

// change the configuration
math.evaluate('config({"__proto__":{"polluted":"yes"}})')
assert.strictEqual(obj.polluted, undefined)
})

it('should not allow polluting the Object prototype by creating an object in the expression parser', () => {
const obj = {}
assert.strictEqual(obj.polluted, undefined)

// change the configuration
math.evaluate('a = {"__proto__":{"polluted":"yes"}}')
assert.strictEqual(obj.polluted, undefined)
})
})

function isPlainObject (object) {
Expand Down
8 changes: 8 additions & 0 deletions test/unit-tests/utils/object.test.js
Expand Up @@ -141,6 +141,14 @@ describe('object', function () {

delete Object.prototype.foo
})

it('should not pollute Object.__proto__', function () {
const obj = {}
assert.strictEqual(obj.polluted, undefined)

deepExtend(obj, JSON.parse('{"__proto__":{"polluted":"yes"}}'))
assert.strictEqual(obj.polluted, undefined)
})
})

describe('deepEqual', function () {
Expand Down

0 comments on commit ecb8051

Please sign in to comment.