Mirror: A maybe slightly safer-ish wrapper around eval Function constructors

Readd global proxy wrapper

Changed files
+25 -3
src
+25 -3
src/index.ts
··· 25 25 const _getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; 26 26 const _defineProperty = Object.defineProperty; 27 27 const _create = Object.create; 28 + const _slice = Array.prototype.slice; 28 29 29 30 type Object = Record<string | symbol, unknown>; 30 31 ··· 75 76 if (new.target === undefined) { 76 77 return target.apply(this, arguments); 77 78 } else { 78 - return new (target.bind.apply(target, arguments)); 79 + const args = _slice.call(arguments); 80 + args.unshift(null); 81 + return new (target.bind.apply(target, args)); 79 82 } 80 83 }) 81 84 : _create(null); ··· 131 134 standin.prototype = _create(null); 132 135 } 133 136 134 - return freeze(standin); 137 + return toplevel ? standin : freeze(standin); 135 138 } 136 139 137 140 let safeGlobal: Record<string | symbol, unknown> | void; ··· 208 211 209 212 // Lastly, we also disallow certain property accesses on the safe global 210 213 // Wrap any given target with a Proxy preventing access to unscopables 211 - return freeze(safeGlobal!); 214 + if (typeof Proxy === 'function') { 215 + // Wrap the target in a Proxy that disallows access to some keys 216 + return (safeGlobal = new Proxy(safeGlobal!, { 217 + // Return a value, if it's allowed to be returned and mask this value 218 + get(target, _key) { 219 + const key = safeKey(target, _key); 220 + return !ignore[_key] && key !== undefined ? target[key] : undefined; 221 + }, 222 + has(_target, _key) { 223 + return true; 224 + }, 225 + set: noop, 226 + deleteProperty: noop, 227 + defineProperty: noop, 228 + getOwnPropertyDescriptor: noop, 229 + })); 230 + } else { 231 + // NOTE: Some property accesses may leak through here without the Proxy 232 + return freeze(safeGlobal!); 233 + } 212 234 } 213 235 214 236 interface SafeFunction {