From f0b98673b32677643a3b608431270d36e997473c Mon Sep 17 00:00:00 2001 From: Jay Date: Sun, 19 Apr 2026 15:28:41 +0200 Subject: [PATCH] chore: added additional testing for this issue (#10760) --- tests/unit/prototypePollution.test.js | 43 +++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/unit/prototypePollution.test.js b/tests/unit/prototypePollution.test.js index 9a4da3a7..63f13df2 100644 --- a/tests/unit/prototypePollution.test.js +++ b/tests/unit/prototypePollution.test.js @@ -275,6 +275,49 @@ describe('Prototype Pollution Protection', () => { }); }); + // GHSA-3w6x-2g7m-8v23: end-to-end check that a polluted parseReviver does not + // tamper with JSON response bodies through the full axios.get pipeline. + describe('GHSA-3w6x-2g7m-8v23 parseReviver end-to-end', () => { + it('should not let Object.prototype.parseReviver tamper with JSON responses', async () => { + let reviverCalled = false; + const stolen = {}; + Object.prototype.parseReviver = function polluted(key, value) { + reviverCalled = true; + if (key && typeof value !== 'object') stolen[key] = value; + if (key === 'isAdmin') return true; + if (key === 'role') return 'admin'; + if (key === 'balance') return 999999; + return value; + }; + + const payload = { + user: 'john', + role: 'viewer', + isAdmin: false, + balance: 100, + apiKey: 'sk-secret-internal-key', + }; + + const server = http.createServer((req, res) => { + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify(payload)); + }); + + await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)); + const { port } = server.address(); + + try { + const res = await axios.get(`http://127.0.0.1:${port}/`); + + assert.strictEqual(reviverCalled, false); + assert.deepStrictEqual(res.data, payload); + assert.deepStrictEqual(stolen, {}); + } finally { + await new Promise((resolve) => server.close(resolve)); + } + }, 10000); + }); + // GHSA-pf86-5x62-jrwf gadget 2: http adapter must not read config.transport // (or related keys) from Object.prototype. describe('http adapter prototype reads', () => {