fix(cli): block config prototype pollution (#54)

This commit is contained in:
lazyGPT07 2026-06-13 23:52:20 -06:00 • committed by GitHub
parent f8040e9736
commit a4cc229120
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 59 additions and 4 deletions

View file

@ -0,0 +1,40 @@
import { describe, expect, it } from "vitest";
import { getConfigValue, mergeConfig, setConfigValue, type JsonObject } from "./config.js";
describe("config helpers", () => {
it("sets and reads nested own properties", () => {
const config: JsonObject = {};
setConfigValue("waiting.arcade.defaultGame", "snake", config);
expect(getConfigValue("waiting.arcade.defaultGame", config)).toBe("snake");
});
it.each(["__proto__", "prototype", "constructor"])(
"rejects unsafe path key: %s",
(key) => {
const marker = "logicsrcPrototypePollution";
const config: JsonObject = {};
expect(() => setConfigValue(`${key}.${marker}`, "true", config)).toThrow(
`Unsafe config key: ${key}`
);
expect(Object.hasOwn(Object.prototype, marker)).toBe(false);
}
);
it("rejects unsafe keys while merging parsed config", () => {
const override = JSON.parse(
'{"__proto__":{"logicsrcPrototypePollution":true}}'
) as JsonObject;
expect(() => mergeConfig({}, override)).toThrow("Unsafe config key: __proto__");
expect(Object.hasOwn(Object.prototype, "logicsrcPrototypePollution")).toBe(false);
});
it("does not read inherited config values", () => {
const config = Object.create({ inherited: "secret" }) as JsonObject;
expect(getConfigValue("inherited", config)).toBeUndefined();
});
});