By NHI Mgmt Group Editorial TeamBased on ActiveFence: “Poisoned Python Bytes & Malicious Caches” (July 29, 2026)

TL;DR: A 4-byte change to a Python .pyc header can make malicious bytecode run while source review, static scanning, and even VirusTotal still see an innocent .py file, according to ActiveFence. The result is a supply-chain trust gap that also affects AI agent skill bundles and any workflow that treats cached runtime artifacts as non-executable.


At a glance

What this is: ActiveFence demonstrates that poisoned Python bytecode can execute while source code and scanners remain clean, exposing a cache trust gap in software and AI supply chains.

Why it matters: IAM, NHI, and platform teams should treat cached runtime artifacts as executable trust boundaries because hidden bytecode can bypass review, scanning, and package controls.

By the numbers:

  • The poisoned cache was undetectable by every antivirus on VirusTotal, and all 70 antivirus engines missed it.

Context

Python bytecode caches are a performance mechanism, but they also create a security boundary that most review processes ignore. When the interpreter trusts a cached .pyc file, the runtime can execute code that is not visible in the source file auditors, scanners, and developers believe they are reviewing. That matters wherever build outputs, packages, or agent skill bundles are promoted as trusted artifacts.

The identity and governance angle is strongest where software supply chains intersect with non-human identities and agentic systems. If a deployment pipeline, AI skill bundle, or packaged workload can carry an executable cache file, then the trust decision moves from source review to runtime artifact handling. That is a control problem, not just a Python implementation detail.

For security teams, this is a typical example of a hidden artifact trust gap rather than an exotic edge case. Any environment that treats generated files as non-executable is exposed to the same failure mode unless it validates, strips, or blocks cached bytecode before release.


Key questions

Q: How should security teams handle poisoned .pyc caches in release pipelines?

A: Treat cached bytecode as executable output, not as disposable build residue. The safest pattern is to strip __pycache__ from release artefacts, rebuild from source in controlled environments, and require runtime validation for any hash-based cache that remains. That closes the gap between what reviewers inspect and what the interpreter actually runs.

Q: Why do poisoned Python caches create a supply-chain risk?

A: Because the runtime trusts the compiled artefact, not just the source file humans review. A compromised build step can distribute a malicious .pyc alongside an innocent .py, and downstream consumers may execute the cache without ever seeing the payload in code review or static scanning.

Q: What signs indicate that Python bytecode should not be trusted?

A: A .pyc file that ships with the application, appears in a package or skill bundle, or uses unchecked-hash mode should be treated as suspicious. Any mismatch between source review, runtime behaviour, and packaged artefacts is a warning that the cache is carrying execution trust the source does not justify.

Q: Should organisations allow runtime caches in AI agent skill bundles?

A: Only if they can validate and govern those caches as executable content. Agent skills are often trusted too quickly, so the safer default is to reject bundled bytecode, rebuild from source at deployment, and apply the same integrity rules to skills that you would apply to any other software supply artefact.


Technical breakdown

How Python .pyc cache validation works

Python compiles source into bytecode and stores it in .pyc files so later imports can skip recompilation. The interpreter decides whether the cache is valid by checking a small header that records either source timestamps or a hash. In checked-hash mode, Python revalidates the source on import. In unchecked-hash mode, the same hash metadata exists, but the interpreter trusts the cache without consulting it. That is why a one-bit flag change can redirect execution away from the source that reviewers inspect and toward a cache that they never intended to trust.

Practical implication: Treat cache validation mode as a security control, not a build preference.

Why source review and static scanners miss poisoned caches

Source review, diffing, and most static analysis tools inspect the .py file, not the compiled bytecode that Python actually executes. A poisoned .pyc can therefore diverge silently from the visible source. Signature-based scanners also struggle because marshalled bytecode lacks the normal text patterns, syntax tree structure, and entropy clues that defenders rely on. The result is a classic provenance split: the artifact humans approve is not the artifact the runtime consumes.

Practical implication: Validate runtime artifacts themselves, not only the source that produced them.

Why AI agent skill bundles widen the exposure surface

AI agent skill bundles and similar packaged workflows are attractive targets because they are small, trusted by default, and often distributed as convenience artifacts rather than scrutinised software. If a bundle includes __pycache__ or shipped .pyc files, a compromised build step can hide malicious execution behind apparently benign source. This is especially relevant for agent platforms that load tools or skills dynamically, because trust in the package often substitutes for trust in each runtime component.

Practical implication: Strip or rebuild cached artifacts before promoting agent skills or packaged workflows.


Threat narrative

Attacker objective: The attacker wants malicious code to execute from a trusted package or cache while defenders continue to see and approve an innocent source file.

  1. Entry occurs when a malicious or compromised build process inserts a poisoned .pyc cache alongside an innocent-looking .py source file.
  2. Credential or trust abuse happens when the interpreter accepts unchecked-hash bytecode and skips source validation on import.
  3. Impact occurs when the runtime executes hidden bytecode while reviewers, scanners, and downstream consumers believe they approved benign source.

Read and download The State of NHI & AI Agent Breach Report 2026, covering 200+ breaches impacting Non-Human Identities including AI Agents.


NHI Mgmt Group analysis

Cache provenance, not source provenance, is the control boundary: this article shows that a build artefact can become the real execution unit while source review continues to provide false reassurance. That is a governance failure in software supply chains because the trust decision is being made at the wrong layer. Practitioners should treat any environment that ships cached bytecode as a provenance problem, not merely a language runtime detail.

Unchecked runtime artefacts create a hidden trust gap that conventional scanning will miss: the defensive assumption that scanners and code review see what the runtime sees is no longer safe when .pyc files can be substituted or altered. This is the same class of problem that appears in other non-human trust chains, including packaged AI skills and machine-generated workflow artefacts. The control question is whether the runtime artifact itself is validated before execution.

AI agent skill bundles inherit the weakest packaging rule in the pipeline: once a skill package is treated as trusted content, hidden caches can become an execution backdoor for the agent that loads them. That means agent governance must include artifact hygiene, not only permission design or prompt safety. Runtime artifact trust gap: any control set that ignores compiled outputs will miss the real execution path, so the security boundary must move to deploy-time validation and cache stripping.

OWASP-NHI is relevant here because cached code behaves like a delegated runtime identity: the bytecode, not the source file, is what the system effectively authorises to run. That maps to the broader NHI problem of trusting artefacts that act on behalf of humans or pipelines without sufficient lifecycle governance. The practical conclusion is that executable caches need inventory, validation, and offboarding just like any other non-human credentialed asset.

From our research library:

What this signals

Runtime artifact governance now matters as much as source governance: packaged caches can move execution away from the file reviewers think they approved, so teams need deploy-time validation and artifact stripping before promotion. For AI agent workloads this is particularly important because the skill bundle, not the source repo, often becomes the trusted delivery unit.

The supply-chain lesson is broader than Python. Any pipeline that treats generated files as inert can be bypassed by a malicious build step, and that includes environments where non-human identities receive code, skills, or workflow packages from third parties. According to the Ultimate Guide to NHIs, 92% of organisations expose NHIs to third parties, raising concerns about supply chain security.


For practitioners

  • Block shipped .pyc and __pycache__ artefacts Refuse packages, wheels, tarballs, containers, and AI skill bundles that carry cached Python bytecode unless the cache is explicitly validated and required for execution.
  • Force hash validation at runtime Run Python with --check-hash-based-pycs=always in security-sensitive environments so hash-based caches cannot silently bypass source checks.
  • Disable cache writes where integrity matters Use PYTHONDONTWRITEBYTECODE=1 and -B in build, test, and sensitive execution paths to stop new caches being created in the first place.
  • Strip cached artifacts before promotion Remove __pycache__ directories from release bundles and rebuild Python artefacts from source at deploy time rather than promoting generated bytecode.

Key takeaways

  • The problem is not Python syntax, it is the mismatch between reviewed source and executable cache, which lets hidden code run without obvious signs.
  • The evidence in this case is stark: a 4-byte header change was enough to make malicious bytecode execute, and VirusTotal missed the poisoned samples.
  • The control that matters most is runtime artifact governance, including cache stripping, forced validation, and rejecting shipped bytecode in trusted packages.

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 and MITRE ATT&CK address the attack and risk surface, while NIST CSF 2.0 and CIS Controls v8 set the governance and control requirements practitioners need to meet.

FrameworkControl / ReferenceRelevance
OWASP Non-Human Identity Top 10NHI-03 — Vulnerable Third-Party NHIPackaged caches and skill bundles create third-party trust exposure in the execution path.
NHI-10 — Human Use of NHIDevelopers and pipeline operators may unknowingly trust artefacts that act on their behalf.
Recommendation — Audit third-party packages and bundles for executable caches before allowing them into runtime. Restrict manual approval of generated artefacts and validate what the runtime actually executes.
MITRE ATT&CKTA0001;TA0006;TA0010 — Initial Access; Credential Access; ExfiltrationThe technique relies on trusted artefacts to gain execution and conceal malicious behaviour.
Recommendation — Map poisoned build artefacts to ATT&CK and hunt for hidden execution in supply-chain pipelines.
NIST CSF 2.0PR.DS-10 — Data in Transit is ProtectedIntegrity of delivered artefacts is central to preventing malicious code from travelling through releases.
Recommendation — Apply CSF integrity controls to packages and build outputs before they reach production.
CIS Controls v8CIS-16 — Application Software SecurityCIS application security guidance fits poisoned code entering software distribution channels.
Recommendation — Harden software release pipelines so generated artefacts are validated before deployment.

Key terms

  • Python Bytecode Cache: A Python bytecode cache is a compiled .pyc artefact that lets the interpreter reuse previously generated bytecode instead of recompiling source. It improves performance, but it also creates a trust boundary because the runtime may execute a cached object rather than the file a reviewer inspected.
  • Unchecked-Hash Mode: A Python .pyc validation mode in which the interpreter trusts cached bytecode without rechecking that it still matches the source. It is useful for performance and reproducible builds, but becomes dangerous when a cache can be replaced or tampered with.
  • Runtime Artefact Trust Gap: A runtime artefact trust gap is the difference between trusting reviewed source code and trusting the generated files that actually run. It appears when build outputs, caches, or intermediates can be changed after approval and before execution, especially in automated pipelines.
  • Supply-Chain Cache Poisoning: Supply-chain cache poisoning is the manipulation of a build or package cache so downstream consumers execute hidden or altered code. The risk is not limited to source repositories, because the poisoned artefact can ride through distribution channels that assume cached content is benign.

Deepen your knowledge

The NHI Foundation Level course, the industry's only accredited NHI security programme, covers NHI governance, machine identity security, and secrets management. It helps practitioners connect identity controls to the supply chains and runtime artefacts their programmes depend on.
NHIMG Editorial Note
Published by the NHIMG editorial team on August 18, 2026.
Updated on October 12, 2026.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org