Join our Newsletter — 33% off our NHI Course

What breaks when an npm package can evaluate untrusted configuration as code?

The security boundary breaks because the parser can recover host runtime primitives, escape any intended sandbox, and execute attacker-controlled JavaScript in a trusted process. At that point the package is no longer just a dependency risk. It becomes a remote code execution path that can reach secrets, environment variables, and operating-system persistence mechanisms.

Why This Matters for Security Teams

When an npm package treats untrusted configuration as executable logic, the risk is no longer confined to dependency hygiene. The package can become an execution broker inside a trusted build or runtime process, which means attacker-controlled input may inherit access to environment variables, tokens, files, and network reach. That shifts the issue from software quality to identity compromise and secret exposure, especially in pipelines that already rely on broad service account privileges. NHI Mgmt Group notes that 30.9% of organisations still store long-term credentials directly in code, which makes this class of bug much easier to weaponise.

This is the same failure pattern seen in Shai Hulud npm malware campaign and Nx Package Attack — 2,300+ Credentials Leaked, where the package boundary was used to reach secrets rather than merely corrupt application output. Current guidance from NIST SP 800-53 Rev 5 Security and Privacy Controls still assumes software components can be constrained by code review, least privilege, and input validation, but that only works when configuration is data and not an alternate execution path. In practice, many security teams discover this only after a build agent has already exposed tokens or been used to persist access.

How It Works in Practice

The critical failure is usually parser trust. A package that evaluates configuration as code may use dynamic evaluation, expression interpolation, template compilation, or plugin hooks that resolve into arbitrary JavaScript. Once an attacker controls that input, they can often recover runtime primitives, reach global objects, and chain into file system or process APIs. In a Node.js environment, that can mean secrets in environment variables, tokens in dotfiles, cloud credentials injected by CI, or post-exploitation actions such as writing persistence into startup paths.

Operationally, the safest design is to keep configuration declarative and to treat anything executable as untrusted code that requires explicit review, signing, and isolation. For npm-based systems, that means separating parsing from evaluation, disabling dynamic execution where possible, and running build steps under tightly scoped identities rather than broad project-wide service accounts. Ultimate Guide to Non-Human Identities is useful here because the same controls that limit service-account blast radius also limit how far a compromised package can move. On the technical side, teams should pair this with policy-enforced dependency controls and runtime guardrails informed by NIST SP 800-53 Rev 5 Security and Privacy Controls.

  • Prefer safe parsers that reject executable expressions instead of interpreting them.
  • Run package install and build steps with ephemeral credentials and narrow scopes.
  • Store secrets in vaults, not in process environment or repository configuration.
  • Instrument CI and runtime monitoring for unexpected child processes, network egress, and file writes.

This guidance tends to break down in shared build runners and monorepo toolchains because inherited environment variables, cached dependencies, and permissive plugin ecosystems make it hard to prove what code actually executed.

Common Variations and Edge Cases

Tighter parsing and sandboxing often increases developer friction and integration cost, so organisations have to balance safety against package flexibility. That tradeoff is especially sharp in tools that support user-defined transforms, templating, or “smart” configuration, because best practice is evolving and there is no universal standard for how much embedded logic should be allowed.

One common edge case is a package that does not explicitly call eval, but still evaluates attacker input through indirect paths such as schema hooks, templating engines, or deserialisation helpers. Another is CI systems that assume package installation is low risk while still exposing deployment tokens, cloud credentials, or signing keys to the same process. The Miasma and Hades Supply Chain Worms research shows why that assumption is dangerous once malicious logic can propagate through build and publishing workflows. The right question is not only whether the package is trusted, but whether the execution context is allowed to trust its input at all.

Another practical exception is local developer tooling, where teams sometimes accept more expressive configuration to reduce friction. That can be reasonable, but only if the tool runs without standing privileges and cannot reach production secrets. Without that separation, a single malicious dependency can turn a convenience feature into a full compromise path, which is why the attack surface must be reviewed as identity exposure, not just as application logic.

Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

OWASP Non-Human Identity Top 10, OWASP Agentic AI Top 10 and CSA MAESTRO address the attack and risk surface, while NIST AI RMF and NIST CSF 2.0 set the governance and control requirements practitioners need to meet.

Framework Control / Reference Relevance
OWASP Non-Human Identity Top 10 NHI-01 Untrusted config execution often exposes NHI secrets and service account material.
OWASP Agentic AI Top 10 A-02 Dynamic code evaluation mirrors agent-like runtime execution from untrusted input.
CSA MAESTRO TRM-03 MAESTRO emphasizes runtime trust decisions for dynamic tool and code execution.
NIST AI RMF GOVERN AI RMF governance applies to uncontrolled runtime behavior and tool exposure.
NIST CSF 2.0 PR.AC-4 Least privilege limits how far a compromised package can move in the environment.

Reduce secret blast radius by isolating package runtimes from long-lived NHI credentials and vault access.