Highcharts Demo

author(s): Torstein Hønsi

by Black Label

HTML

<script src="https://code.highcharts.com/13.0.2/highcharts.js"></script>
<div id="container" style="height: 400px"></div>

JavaScript

// Workaround fix for all affected Highcharts versions: 6.1.0-13.0.2
;!function(t){if(t&&t.Point&&!t.Point.prototype.protoPollutionPatched){var o=t.Point.prototype,r=o.optionsToObject,e=o.setNestedProperty,n=Object.prototype.hasOwnProperty;o.optionsToObject=function(t){if(t&&"object"==typeof t&&!Array.isArray(t)&&(n.call(t,"__proto__")||n.call(t,"constructor"))){var o={};for(var e in t)n.call(t,e)&&!c(e)&&(o[e]=t[e]);t=o}return r.call(this,t)},o.setNestedProperty=function(t,o,r){return String(r).split(".").some(c)?t:e.call(this,t,o,r)},o.protoPollutionPatched=!0}function c(t){return"__proto__"===t||"constructor"===t}}(Highcharts);
// End of the workaround fix


const polluted = () => {
    const hit = [];
    if ({}.polluted || {}.alsoPolluted) {
        hit.push('Object.prototype');
    }
    if ({}[0] !== undefined) {
        hit.push('Object.prototype[0]');
    }
    if (Object[0] !== undefined || Object[1] !== undefined) {
        hit.push('Object');
    }
    return hit;
};

Highcharts.chart('container', {
    title: { text: 'HC v' + Highcharts.version },
    yAxis: { title: { text: null } },
    series: [{
        // Vector 1: dotted keys, expanded by `setNestedProperty`
        type: 'column',
        name: 'series.keys',
        keys: ['__proto__.polluted', 'constructor.prototype.alsoPolluted', 'y'],
        data: [['yes', 'yes', 1]]
    }]
}, (chart) => {
    let broke = '';

    // Vector 2: own `__proto__` and `constructor` keys in a point config,
    // exactly as `JSON.parse` of an untrusted response produces them
    try {
        chart.addSeries({
            type: 'column',
            name: 'point config',
            data: JSON.parse(
                '[{"y":2,"__proto__":{"polluted":"yes"},' +
                '"constructor":{"alsoPolluted":"yes"}}]'
            )
        });
    } catch (e) {
        broke = ', chart broke on it: ' + e.message;
    }

    const hit = polluted();

   ...