Skip to content

Commit

Permalink
Fixed #14883, possible prototype pollution through chart configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
TorsteinHonsi committed Jan 7, 2021
1 parent 2ed7a26 commit fead359
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 9 deletions.
4 changes: 4 additions & 0 deletions js/Core/Utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,10 @@ function merge() {
copy = {};
}
objectEach(original, function (value, key) {
// Prototype pollution (#14883)
if (key === '__proto__' || key === 'constructor') {
return;
}
// Copy the contents of objects, but not arrays or DOM nodes
if (isObject(value, true) &&
!isClass(value) &&
Expand Down
27 changes: 18 additions & 9 deletions samples/unit-tests/highcharts/constructors/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,25 @@ QUnit.test('Highcharts', function (assert) {
}
});

chart = new Highcharts.Chart({
chart: {
renderTo: 'container'
const options = JSON.parse(`{
"chart": {
"__proto__": {
"prototypePollution": true
},
"renderTo": "container"
},
series: [
{
data: [1, 2, 3, 4]
}
]
});
"series": [{
"data": [1, 2, 3, 4]
}]
}`);

chart = new Highcharts.Chart(options);

assert.strictEqual(
window.prototypePollution,
undefined,
'Prototype pollution through JSON options should not be possible'
);

assert.strictEqual(
chart.series[0].yData.join(','),
Expand Down
32 changes: 32 additions & 0 deletions samples/unit-tests/utilities/utilities/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,38 @@
);
});

QUnit.test('Merge', assert => {

// test filtering of __proto__
const objProto = JSON.parse(`{
"__proto__": {
"pollutedByProto": true
}
}`);
Highcharts.merge({}, objProto);
assert.strictEqual(
typeof pollutedByProto, // eslint-disable-line no-undef
'undefined',
'The prototype (and window) should not be polluted through merge'
);

// test filtering of constructor
const objConstructor = JSON.parse(`{
"constructor": {
"prototype": {
"pollutedByConstructor": true
}
}
}`);
Highcharts.merge({}, objConstructor);
assert.strictEqual(
typeof {}.pollutedByConstructor, // eslint-disable-line no-undef
'undefined',
'The prototype (and window) should not be polluted through merge'
);

});

QUnit.test('PInt', function (assert) {
// test without a base defined
assertEquals(assert, 'base not defined', 15, pInt('15'));
Expand Down
5 changes: 5 additions & 0 deletions ts/Core/Utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,11 @@ function merge<T>(): T {

objectEach(original, function (value, key): void {

// Prototype pollution (#14883)
if (key === '__proto__' || key === 'constructor') {
return;
}

// Copy the contents of objects, but not arrays or DOM nodes
if (isObject(value, true) &&
!isClass(value) &&
Expand Down

0 comments on commit fead359

Please sign in to comment.