diff --git a/src/helpers/helpers.core.js b/src/helpers/helpers.core.js index 279f9408492..9345deae7ad 100644 --- a/src/helpers/helpers.core.js +++ b/src/helpers/helpers.core.js @@ -1,5 +1,9 @@ 'use strict'; +function isValidKey(key) { + return ['__proto__', 'prototype', 'constructor'].indexOf(key) === -1; +} + /** * @namespace Chart.helpers */ @@ -181,6 +185,12 @@ var helpers = { * @private */ _merger: function(key, target, source, options) { + if (!isValidKey(key)) { + // We want to ensure we do not copy prototypes over + // as this can pollute global namespaces + return; + } + var tval = target[key]; var sval = source[key]; @@ -196,6 +206,12 @@ var helpers = { * @private */ _mergerIf: function(key, target, source) { + if (!isValidKey(key)) { + // We want to ensure we do not copy prototypes over + // as this can pollute global namespaces + return; + } + var tval = target[key]; var sval = source[key]; diff --git a/test/specs/helpers.core.tests.js b/test/specs/helpers.core.tests.js index 80b0640b2cc..7efafd18bfd 100644 --- a/test/specs/helpers.core.tests.js +++ b/test/specs/helpers.core.tests.js @@ -277,6 +277,11 @@ describe('Chart.helpers.core', function() { }); describe('merge', function() { + it('should not allow prototype pollution', function() { + var test = helpers.merge({}, JSON.parse('{"__proto__":{"polluted": true}}')); + expect(test.prototype).toBeUndefined(); + expect(Object.prototype.polluted).toBeUndefined(); + }); it('should update target and return it', function() { var target = {a: 1}; var result = helpers.merge(target, {a: 2, b: 'foo'});