Skip to content

Commit dd2190b

Browse files
authored
Merge pull request #288 from zjs81/fix/complete-prototype-pollution-protection
Enhance prototype pollution protection
2 parents 8e96e63 + 72c8490 commit dd2190b

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

src/Decoder.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -651,8 +651,8 @@ export class Decoder<ContextType = undefined> {
651651
continue DECODE;
652652
}
653653
} else if (state.type === STATE_MAP_KEY) {
654-
if (object === "__proto__") {
655-
throw new DecodeError("The key __proto__ is not allowed");
654+
if (object === "__proto__" || object === "constructor" || object === "prototype") {
655+
throw new DecodeError(`The key ${object} is not allowed`);
656656
}
657657

658658
state.key = this.mapKeyConverter(object);

test/prototype-pollution.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,40 @@ describe("prototype pollution", () => {
1919
}, DecodeError);
2020
});
2121
});
22+
23+
context("constructor exists as a map key", () => {
24+
it("raises DecodeError in decoding", () => {
25+
const o = {
26+
foo: "bar",
27+
};
28+
// override constructor as an enumerable property
29+
Object.defineProperty(o, "constructor", {
30+
value: new Date(0),
31+
enumerable: true,
32+
});
33+
const encoded = encode(o);
34+
35+
throws(() => {
36+
decode(encoded);
37+
}, DecodeError);
38+
});
39+
});
40+
41+
context("prototype exists as a map key", () => {
42+
it("raises DecodeError in decoding", () => {
43+
const o = {
44+
foo: "bar",
45+
};
46+
// override prototype as an enumerable property
47+
Object.defineProperty(o, "prototype", {
48+
value: new Date(0),
49+
enumerable: true,
50+
});
51+
const encoded = encode(o);
52+
53+
throws(() => {
54+
decode(encoded);
55+
}, DecodeError);
56+
});
57+
});
2258
});

0 commit comments

Comments
 (0)