diff --git a/src/index.ts b/src/index.ts index d3971c8..83b282d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,18 @@ const pm = require("picomatch"); export type Key = string | number | (() => string | number); +const ILLEGAL_KEYS = new Set(["prototype", "constructor", "__proto__"]); + +function isIllegalKey(key: string): Boolean { + return ILLEGAL_KEYS.has(key); +} + +function disallowProtopath(key: string | number): void { + if (typeof key === "string" && isIllegalKey(key)) { + throw new Error("Unsafe key encountered: " + key) + } +} + function getSegments(path: Key | Key[]): (string | number)[] { let segments = []; if (typeof path === "string") { @@ -180,6 +192,7 @@ export default class PTree { for (let i = 0; i < segments.length; i++) { const current = obj; const seg = segments[i]; + disallowProtopath(seg); if (i < segments.length - 1) { obj = (obj)[seg]; diff --git a/test/index.js b/test/index.js index bcb901e..9b56e9b 100644 --- a/test/index.js +++ b/test/index.js @@ -1,4 +1,5 @@ let $p = require("../dist/").default; +const assert = require("assert") function compare(actual, expected) { console.log( @@ -607,3 +608,15 @@ const obj25 = { compare($p.from(obj25).wildcard("a.*").length, 2); compare($p.from(obj25).wildcard("b.**").length, 4); compare($p.from(obj25).wildcard("d.*").length, 0); + +function isProtoPathPolluted() { + const t = new $p({}); + t.set('__proto__.polluted', true) +} + +function testProtoPathPollution() { + assert.throws(isProtoPathPolluted, "Test failed for Proto Path.") + console.log("Test passed.") +} + +testProtoPathPollution(); \ No newline at end of file