You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
HIR pass identifies dynamic property access on stdlib namespaces
Build fails at offending call site with clear message + offending package
Site-annotation opt-out (// @perry-allow-dynamic)
Host package.json opt-out for specific deps
User-code reflection on user objects unaffected
Works together with the per-package capability issue: a string-based escape can't bypass the capability check because the dynamic dispatch itself is rejected
Part of the supply-chain hardening series. Host-app-controlled. Zero runtime cost.
Activity
style: cargo fmt for #503 PR
docs(#503): tag typescript fences with no-test directive for doc-test…
feat(security): #503 — refuse compile-time dynamic dispatch on stdlib…
feat(security): #496 --lockdown compile flag refuses arbitrary-code-e…
feat(security): #496 --lockdown compile flag refuses arbitrary-code-e…
fix(security): #996 — ignore @perry-allow-dynamic inside node_modules (…
fix(fetch): Request body methods callable as value / computed key (#1698
fix(fetch): Request body methods callable as value / computed key (#1698
fix(lockdown): #503 guard must not fire on locals shadowing a stdlib …
fix(lockdown): #503 guard must allow auditable ns[dynamicKey].staticM…
release: v0.5.1028 — post-v0.5.1027 catch-up batch (#1755)
feat(hir): classify new Function/eval call sites + refusal diagnostic (…
feat(compiler): self-hosted build-time precompile() — Perry runs its …
fix(security): allow dynamic stdlib member access by default; gate U0…
fix(hir): dispatch direct computed-key Math/JSON/Object method calls (#…