Join our Newsletter — 33% off our NHI Course

What do security teams get wrong about import-time malware?

They focus on the malicious function call and miss the import boundary. In Python, top-level package code can run before any intended application logic, which means the theft can happen during normal dependency loading. Security teams need to control what secrets are present at that moment, not just what files are later detected as malicious.

Why This Matters for Security Teams

Import-time malware is dangerous because it executes before the application ever reaches the code path defenders usually inspect. That makes the real control point the dependency-loading boundary, where package initialisation, environment access, and secret retrieval can happen automatically. Security teams often over-index on scanning for malicious functions after install, while the attacker is already harvesting tokens, API keys, or CI credentials.

This is the same failure pattern highlighted in NHIMG research on the Shai Hulud npm malware campaign, where normal software supply-chain behaviour became the attack path. It also fits the broader credential exposure seen in the CircleCI Breach, where access at the wrong moment turned a software event into a secrets event. NHI Mgmt Group data shows 96% of organisations store secrets outside secrets managers in vulnerable locations, which means import-time code often encounters material worth stealing. Current best practice is to reduce what is available to code at load time, not just detect what looks malicious later.

Practitioners should treat package import as an execution event, not a passive file-read. In practice, many security teams encounter credential theft only after the dependency has already been trusted by the build or runtime pipeline, rather than through intentional pre-execution controls.

How It Works in Practice

Top-level code in a Python package can run as soon as the module is imported. That means an attacker does not need a user-triggered function call if they can place logic in package initialisation, transitive dependencies, or setup-related paths. The practical defense is to assume import-time code may be hostile and to limit the secrets, tokens, and network reach available during dependency loading.

Security teams should combine supply-chain controls with runtime containment. CIS Controls v8 supports the broader discipline of managing software assets, hardening configurations, and reducing exposure in build environments. That matters here because import-time malware often succeeds through convenience: package installs, automated tests, and CI jobs frequently run with too much ambient access.

  • Keep secrets out of install and import paths whenever possible, especially in CI/CD and ephemeral build runners.
  • Use short-lived credentials with narrow scope so an imported package cannot reuse long-lived access.
  • Separate dependency resolution from secret-bearing runtime contexts.
  • Block outbound network access during install unless the build step explicitly requires it.
  • Prefer lockfiles, hash pinning, and package integrity checks, but do not treat those as sufficient by themselves.

NHIMG guidance on the Ultimate Guide to Non-Human Identities is relevant because import-time malware often steals non-human credentials first, not human passwords. The real objective is to prevent code that is merely being loaded from inheriting production-grade access. These controls tend to break down when build pipelines reuse developer secrets, because the import boundary then becomes a live exfiltration point.

Common Variations and Edge Cases

Tighter import controls often increase build friction, requiring organisations to balance developer velocity against secret exposure. That tradeoff becomes sharper in data science notebooks, plugin-based applications, and monorepos, where imports are frequent, transitive, and hard to fully predict.

There is no universal standard for this yet, but current guidance suggests treating high-risk dependency events differently from ordinary application start-up. For example, plugin ecosystems may legitimately execute code at load time, while packaging tools may import modules during metadata collection. In those environments, strict allowlists alone are not enough because the same action can be both normal and exploitable.

Teams should also be careful not to mistake static analysis coverage for runtime safety. A package can look benign in source review and still access local credentials when imported in a privileged environment. The better question is not only whether the code is malicious, but whether the environment is safe for any untrusted package to execute.

NHIMG’s research on the State of Non-Human Identity Security shows how often organisations remain blind to the identities and credentials their systems actually use. That blind spot is exactly what import-time malware exploits. In practice, the weakest point is usually not package trust, but the assumption that loading code is harmless.

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 Import-time malware exploits exposed non-human credentials at execution start.
OWASP Agentic AI Top 10 LLM-04 Autonomous tool execution shares the same pre-action trust failure as import-time code.
CSA MAESTRO MA-02 MAESTRO addresses execution-time governance for software that acts before user intent.
NIST AI RMF GOV-2 AI RMF governance applies to runtime trust and accountability decisions.
NIST CSF 2.0 PR.AC-6 Least privilege limits what import-time code can reach if it runs unexpectedly.

Treat early execution paths as hostile and validate tool access before any autonomous action.