mirror of
https://github.com/tenrok/axios.git
synced 2026-06-17 19:21:29 +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;
|
||||
}
|
||||
|
||||
if (!target[name] || !utils.isObject(target[name])) {
|
||||
if (!utils.hasOwnProp(target, name) || !utils.isObject(target[name])) {
|
||||
target[name] = [];
|
||||
}
|
||||
|
||||
|
||||
@@ -95,4 +95,25 @@ describe('formDataToJSON', () => {
|
||||
expect({}.x).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