The standard string-based obfuscation pattern in malicious npm packages: process["bind"+"ing"]("dns"), globalThis[atob("ZXZhbA==")](), fs[methodName]() where methodName is computed. For stdlib objects specifically, require the method/property name to be a literal at the call site. Catches the dispatch-by-string class of evasion.
Mechanism
HIR pass: when the receiver is a known stdlib namespace (process, fs, crypto, child_process, net, os, path, etc.), require the property/method name to be Expr::String literal (or a compile-time constant that folds to one). Non-literal access on stdlib objects fails compilation.
User-code reflection that legitimately needs dynamic dispatch on user objects is unaffected. Legitimate dynamic dispatch on stdlib (rare) opts in via // @perry-allow-dynamic site annotation or perry.allowDynamicStdlibDispatch: ["pkg"] host config.
Zero runtime cost — compile-time refusal only.
Acceptance
Part of the supply-chain hardening series. Host-app-controlled. Zero runtime cost.
The standard string-based obfuscation pattern in malicious npm packages:
process["bind"+"ing"]("dns"),globalThis[atob("ZXZhbA==")](),fs[methodName]()wheremethodNameis computed. For stdlib objects specifically, require the method/property name to be a literal at the call site. Catches the dispatch-by-string class of evasion.Mechanism
HIR pass: when the receiver is a known stdlib namespace (
process,fs,crypto,child_process,net,os,path, etc.), require the property/method name to beExpr::Stringliteral (or a compile-time constant that folds to one). Non-literal access on stdlib objects fails compilation.User-code reflection that legitimately needs dynamic dispatch on user objects is unaffected. Legitimate dynamic dispatch on stdlib (rare) opts in via
// @perry-allow-dynamicsite annotation orperry.allowDynamicStdlibDispatch: ["pkg"]host config.Zero runtime cost — compile-time refusal only.
Acceptance
// @perry-allow-dynamic)package.jsonopt-out for specific depsPart of the supply-chain hardening series. Host-app-controlled. Zero runtime cost.