mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 09:37:41 +00:00
fix(security): block prototype-polluting keys in deepMerge (#20853)
Reject __proto__, prototype, and constructor keys during deep-merge to prevent prototype pollution when merging untrusted config objects.
This commit is contained in:
@@ -5,6 +5,7 @@ import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
CircularIncludeError,
|
||||
ConfigIncludeError,
|
||||
deepMerge,
|
||||
type IncludeResolver,
|
||||
resolveConfigIncludes,
|
||||
} from "./includes.js";
|
||||
@@ -521,6 +522,31 @@ describe("security: path traversal protection (CWE-22)", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("prototype pollution protection", () => {
|
||||
it("blocks __proto__ keys from polluting Object.prototype", () => {
|
||||
const result = deepMerge({}, JSON.parse('{"__proto__":{"polluted":true}}'));
|
||||
expect((Object.prototype as Record<string, unknown>).polluted).toBeUndefined();
|
||||
expect(result).toEqual({});
|
||||
});
|
||||
|
||||
it("blocks prototype and constructor keys", () => {
|
||||
const result = deepMerge(
|
||||
{ safe: 1 },
|
||||
{ prototype: { x: 1 }, constructor: { y: 2 }, normal: 3 },
|
||||
);
|
||||
expect(result).toEqual({ safe: 1, normal: 3 });
|
||||
});
|
||||
|
||||
it("blocks __proto__ in nested merges", () => {
|
||||
const result = deepMerge(
|
||||
{ nested: { a: 1 } },
|
||||
{ nested: JSON.parse('{"__proto__":{"polluted":true}}') },
|
||||
);
|
||||
expect((Object.prototype as Record<string, unknown>).polluted).toBeUndefined();
|
||||
expect(result).toEqual({ nested: { a: 1 } });
|
||||
});
|
||||
});
|
||||
|
||||
describe("edge cases", () => {
|
||||
it("rejects null bytes in path", () => {
|
||||
const obj = { $include: "./file\x00.json" };
|
||||
|
||||
Reference in New Issue
Block a user