mirror of
https://github.com/tenrok/axios.git
synced 2026-06-20 20:00:40 +03:00
fix(security): defense-in-depth against already-polluted Object.prototype in formDataToJSON (#7413)
* fix(security): harden prototype pollution protection in formDataToJSON Replace falsy check with hasOwnProp in the intermediate-path branch of formDataToJSON's buildPath to prevent write-through into inherited objects. Without this patch, if Object.prototype is already polluted (e.g. via a third-party library or earlier vulnerability), user-supplied FormData paths like 'injected.hijack' traverse the inherited object and mutate Object.prototype in place. With hasOwnProp, the inherited slot is shadowed by a new own property, keeping writes local to the result. This is defense-in-depth: the existing __proto__ guard blocks direct prototype injection, while this change prevents exploitation of an already-polluted prototype chain. Closes #7209 * test(security): use defineProperty + toBe in prototype-pollution regression test --------- Co-authored-by: tommyhgunz14 <tommyhgunz14@users.noreply.github.com> Co-authored-by: Jay <jasonsaayman@gmail.com>
This commit is contained in:
@@ -68,7 +68,7 @@ function formDataToJSON(formData) {
|
|||||||
return !isNumericKey;
|
return !isNumericKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!target[name] || !utils.isObject(target[name])) {
|
if (!utils.hasOwnProp(target, name) || !utils.isObject(target[name])) {
|
||||||
target[name] = [];
|
target[name] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,4 +95,25 @@ describe('formDataToJSON', () => {
|
|||||||
expect({}.x).toEqual(undefined);
|
expect({}.x).toEqual(undefined);
|
||||||
expect({}.y).toEqual(undefined);
|
expect({}.y).toEqual(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not write through to inherited objects on Object.prototype', () => {
|
||||||
|
Object.defineProperty(Object.prototype, 'injected', {
|
||||||
|
value: { hijack: true },
|
||||||
|
configurable: true,
|
||||||
|
writable: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
formData.append('injected.hijack', 'STOLEN');
|
||||||
|
|
||||||
|
const result = formDataToJSON(formData);
|
||||||
|
|
||||||
|
expect(result.injected).toEqual({ hijack: 'STOLEN' });
|
||||||
|
expect(Object.prototype.injected.hijack).toBe(true);
|
||||||
|
} finally {
|
||||||
|
delete Object.prototype.injected;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user