Skip to content

Commit b39f1a9

Browse files
Merge pull request #86 from RebeccaStevens/security/prototype-pollution
2 parents 7436788 + d637db7 commit b39f1a9

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

Diff for: src/deepmerge.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,16 @@ function defaultMergeRecords<
438438
continue;
439439
}
440440

441-
result[key] = propertyResult;
441+
if (key === "__proto__") {
442+
Object.defineProperty(result, key, {
443+
value: propertyResult,
444+
configurable: true,
445+
enumerable: true,
446+
writable: true,
447+
});
448+
} else {
449+
result[key] = propertyResult;
450+
}
442451
}
443452

444453
/* eslint-enable functional/no-loop-statement, functional/no-conditional-statement */

Diff for: tests/deepmerge.test.ts

+16
Original file line numberDiff line numberDiff line change
@@ -539,3 +539,19 @@ test(`merging objects with null prototype`, (t) => {
539539

540540
t.deepEqual(merged, expected);
541541
});
542+
543+
test("prototype pollution", (t) => {
544+
const payload = '{"__proto__":{"a0":true}}';
545+
546+
const x: any = JSON.parse(payload);
547+
const y: any = {};
548+
549+
const merged: any = deepmerge(x, y);
550+
551+
t.deepEqual(JSON.stringify(merged), payload);
552+
553+
t.not(({} as any).a0, true, "Safe POJO");
554+
t.not(x.a0, true, "Safe x input");
555+
t.not(y.a0, true, "Safe y input");
556+
t.not(merged.a0, true, "Safe output");
557+
});

0 commit comments

Comments
 (0)