Target-State Script Injection: Declarative Config and Infrastructure Tools as a Code-Execution Path for AI Agents
Target-state script injection is SSA descriptive wording for a declarative config or infrastructure-as-code tool executing attacker-controlled commands as the documented mechanism for reaching a declared target state, not as a bug in any one tool. Covers chezmoi's documented run_ and modify_ script model, the September 2026 Coder registry compromise that shipped credential-stealing Terraform modules through a data.external block (GHSA-vx42-ghc9-gw65), and the Miasma worm as evidence that AI coding agents already execute repo-shipped setup artifacts without per-file review.
- Target
- Tool & Environment State
- Persistence
- Cross-Session to Shared-System
- Control
- Prevent, Detect, Contain, Recover
- Status
- SSA Working Term
Target-state script injection is SSA descriptive wording for a security-relevant property of tools that converge real filesystem or infrastructure state to a declared target state by executing commands: the convergence step, applying dotfiles, provisioning infrastructure, syncing configuration, is not a data operation a reviewer can treat as inert. It is code execution by design, documented as such by the tools themselves, so an attacker who controls the declaration gets arbitrary command execution the moment anyone, increasingly an AI agent told to "set this up" or "apply this module," runs the convergence step against it.
What it is
The defining object is a source-of-truth declaration, a dotfile repository, an infrastructure-as-code module, a configuration-management playbook, that a tool reconciles against real state through an apply, provision, or sync operation. The defining cause is that these tools embed script or command execution directly into that reconciliation step as a first-class, documented feature, not an edge case: chezmoi runs run_, run_once_, and run_onchange_ scripts, and treats files prefixed modify_ as scripts that receive a file's current contents on standard input and write its new contents to standard output; Terraform supports provisioners and external data sources that run an arbitrary program and read its output back into the plan. The defining consequence is that reviewing the declaration as configuration, skimming it the way a reviewer skims a YAML file or a dotfile, misses that applying it is equivalent to running whatever command the declaration names.
This becomes an agent-state concern specifically because an AI agent is a plausible, and increasingly demonstrated, actor at the apply step. An agent asked to bootstrap a development environment, provision infrastructure from a shared module, or sync a user's dotfiles has no inherent reason to treat "run the standard setup" as higher-risk than any other requested action, and a human reviewing the agent's plan sees "apply configuration," not "execute this script," unless something surfaces the distinction explicitly.
What it is not
- Instruction file poisoning, where the entry path is a file an agent auto-loads as standing instructions to itself, such as CLAUDE.md or
.cursorrules. This entry's tools execute commands as part of reconciling external filesystem or infrastructure state, independent of what the agent believes or intends. - Sandbox configuration escape, where a compromised session writes host-trusted configuration that a later launch reloads with elevated privilege. This entry requires no later reload and no prior compromise: the code runs during the single, documented apply call the declaration was built to trigger.
- Agent command-approval bypass, where a guard approves a command string that an interpreter then rewrites into something else. Nothing is bypassed here; the tool's own documentation states that applying the declaration runs commands.
- A vulnerability specific to chezmoi, Terraform, or any single tool. The sources below show the pattern across a dotfile manager's documented script model and an infrastructure-as-code provisioner's external data source, reached through different attacker footholds.
- Reproducible exploit payloads or step-by-step instructions for weaponizing a specific module or script.
In scope
- Dotfile and configuration-sync tools whose documented apply step runs scripts embedded in the source declaration (chezmoi's
run_,run_once_,run_onchange_, andmodify_conventions, and equivalents in comparable tools). - Infrastructure-as-code provisioners and external data sources that execute a program during planning or provisioning (Terraform's
provisionerblocks anddata "external"sources, and equivalents in comparable tools). - Module and template registries whose compromise lets an attacker substitute a tampered declaration for a trusted one at the point of download, independent of whether the original repository itself was ever touched.
- AI agents or CI pipelines invoking an apply, provision, or sync step against a declaration pulled from a fork, a registry, or a URL that was not reviewed as executable code before the step ran.
- Detection and containment of the apply step itself, rather than of any single vendor's patched defect.
Target state, trust boundary, and persistence
The target state is the real filesystem or infrastructure environment once the apply step finishes converging it to whatever the source declaration specifies, including any side effect a script or provisioner ran along the way. The trust boundary that fails is the assumption that approving a declaration is a lighter-weight decision than approving code, when for these tools the two are the same decision: the declaration's author, whoever last touched the dotfiles repository or the module version being pulled, gets to run commands on every machine that applies it.
Persistence here runs Cross-Session to Shared-System rather than stopping at one compromised run. A poisoned dotfiles repository re-executes its scripts on every future apply by every person who clones it, bounded in chezmoi's case by its own runonce hashing, which prevents an unchanged script from firing twice but does nothing once the script itself is attacker-controlled from the first run. A compromised module-registry entry is worse by scope: it reaches every consumer who resolves that module during the compromise window, independent of whether any individual consumer's own repository or credentials were ever directly attacked.
What the research establishes
chezmoi's own documentation describes the mechanism plainly, not as a caveat. Scripts named with a run_ prefix execute on every chezmoi apply; run_once_ scripts execute once per unique content hash, tracked by a stored SHA256 in chezmoi's own state; run_onchange_ scripts re-execute whenever their content changes. Files prefixed modify_ are treated as scripts that receive a target file's current contents on standard input and whose standard output becomes the new file contents. chezmoi writes each script to a temporary executable file and runs it as ordinary shell code, and the project's own guidance is explicit that this is a deliberate departure from safety-by-design: "scripts break chezmoi's declarative approach and should be used sparingly" (chezmoi, Use scripts to perform actions). Nothing about this is a defect; it is the feature, and a source-state repository that defines such a script has defined code that will run on every machine that applies it.
The same pattern surfaced in a documented incident against infrastructure-as-code tooling rather than dotfiles. On August 31, 2026, an attacker gained unauthorized access to Coder's Cloudflare infrastructure and, for roughly fourteen hours between 07:35 and 21:45 UTC, inserted rogue IP addresses into the server pool behind registry.coder.com, so that some requests for Coder's Terraform modules resolved to attacker-controlled servers instead. Those servers served tampered modules containing an added data "external" block, a Terraform mechanism for running an external program and reading its output back into the plan, that executed during ordinary provisioning. Coder identifies the string data.external.telemetry as the tampered modules' detection signature in provisioner logs. The payload harvested provisioner environment variables and secrets, including cloud and AI-tooling API keys, CI/CD credentials, configuration-file secrets, terminal history, SSH keys, and user OIDC tokens, exfiltrating them over HTTP to the lookalike domain coder-infra.com, registered three days before the compromise began. Coder rated the incident CVSS 4.0 9.0, Critical, published as advisory GHSA-vx42-ghc9-gw65 on September 1, 2026, with no CVE assigned, and shipped patched releases 2.37.0, 2.36.4, 2.35.7, and 2.34.9 (Cloud Security Alliance, Research Note: Coder Registry Compromise Spreads Credential-Stealing Terraform Modules; eSecurity Planet, Coder Registry Compromise: Malicious Terraform Modules Explained). Coder itself is a declarative development-environment platform that provisions workspaces AI coding agents and their credentials run inside, which places this incident's blast radius inside exactly the environments this site covers, independent of whether any single agent action triggered it.
A separate 2026 campaign establishes the other half of the claim: that an AI coding agent treating a repository's standard setup artifact as benign is not a hypothetical. The Miasma worm, reported by SafeDep, pushed a commit disguised as a routine dependency update into more than 120 GitHub repositories, including Azure's durabletask, writing a SessionStart hook into .claude/settings.json, an equivalent hook into .gemini/settings.json, an always-applied rule into .cursor/rules/setup.mdc, and a folder-open task into .vscode/tasks.json, each wired to run a dropper the moment a developer opened the repository in an AI coding agent or editor, or ran the project's own npm test script. The dropper decrypted and ran a credential-stealing payload targeting cloud, Kubernetes, npm, and GitHub secrets (SafeDep, Miasma Worm Targets AI Coding Agents via GitHub Repos). Miasma's entry path is an agent's own configuration and hook files rather than a declarative state-convergence tool, but it demonstrates the precondition this entry depends on directly: an agent, or the editor wrapped around it, already executes a repository's own automatic setup artifact without treating that artifact as code requiring separate review. The same incentive applies with equal force to an agent told to run chezmoi apply against a shared dotfiles repository or terraform apply against a module it resolved from a registry.
Detection: observable signs
- An apply, provision, or sync command (
chezmoi apply,terraform applyorplan, an equivalent reconciliation step) runs against a source declaration pulled from a fork, registry, or URL that was never reviewed as executable code, only as configuration. - A provisioner or apply log shows a script, provisioner block, or external data source that was not present in a previously reviewed version of the same declaration.
- Outbound network activity from an apply or provisioning step targets a newly registered or lookalike domain rather than the environment's expected cloud, package, or telemetry endpoints.
- A dotfile or module's
run_,modify_,provisioner, ordata "external"construct appears for the first time in a diff authored by an external contributor or introduced by a dependency bump. - Credential or network activity follows immediately after an agent- or pipeline-driven "set up," "sync," or "apply" step, with no explicit user request that would account for that specific activity.
Defenses, containment, and recovery
The table below is SSA editorial guidance for defenders. It is neither a standard requirement nor a measured effectiveness ranking.
Control | Transition it interrupts | Applicability | Residual risk and verification |
|---|---|---|---|
Treat every script, provisioner block, or external data source inside a source-state declaration as reviewable code before any apply step runs, not as inert configuration | A reviewer, human or agent, skimming a declaration as data instead of as a command that will execute | Any team or agent workflow that applies dotfiles, infrastructure-as-code modules, or configuration-management playbooks from a shared or external source | Requires reviewers to know these constructs exist in the format; a declaration with no obvious script keyword can still execute through a less familiar mechanism, such as a |
Pin dotfile repositories and infrastructure-as-code modules to a specific, reviewed commit or version hash rather than a branch, tag, or "latest," and re-verify the hash before every apply | A registry or repository compromise silently substituting a tampered declaration for a previously reviewed one | Any apply, provision, or sync step that resolves a dependency from a registry or remote repository | Pinning stops substitution after the review, not a compromise that occurred before the pin was first set; re-review on every intentional version bump. |
Run a diff or dry-run step ( | An agent applying a declaration's full effect, including any embedded script, with no checkpoint before execution | Any unattended or agent-driven apply, provision, or sync workflow | A dry-run can itself be defeated if the tool executes scripts during the dry-run phase; verify that the specific tool's dry-run mode genuinely skips script and provisioner execution. |
Scope the credentials available to an apply or provisioning step narrowly, per environment, rather than granting one broad credential set to every run | The blast radius once any single compromised script or provisioner block executes | Any provisioning pipeline or agent workflow that currently reuses one credential set across environments | Limits consequence, not occurrence; a narrowly scoped credential can still exfiltrate whatever that specific environment legitimately needs. |
Monitor apply and provisioner logs for known compromise signatures, such as an unexpected external data source or a new outbound destination, rather than trusting a module's version string alone | A tampered declaration that matches a previously trusted version string but not a previously trusted behavior | Any team that has resolved modules from a public registry during a disclosed compromise window | Detects known, disclosed signatures; a novel compromise with no published signature yet requires behavioral monitoring, not string matching, to catch. |
Prevention should treat a dotfile manager's script prefixes and an infrastructure-as-code tool's provisioner or external-data constructs as execution surfaces from the start, pinned and reviewed the way any other code dependency would be. Detection should watch the apply or provisioning step itself for unfamiliar scripts, provisioner blocks, or outbound destinations, rather than relying on a declaration's version string or source repository name as a proxy for its current safety. Containment should treat any credential reachable from a compromised apply step as exposed and rotate it, since, as in the Coder incident, the compromised party itself may be unable to confirm which specific downstream deployments were affected. Recovery should re-apply from a known-clean, re-pinned declaration and audit every environment that resolved the compromised version during the exposure window, not only the one where a problem was first noticed.
Boundaries with similar concepts
This differs from instruction file poisoning in what is being targeted. That entry's object is a file an agent auto-loads as standing guidance to its own reasoning. This entry's object is a tool that executes commands on real filesystem or infrastructure state as its documented way of reaching a declared configuration, with no change to the agent's own goals or instructions required for the attack to succeed.
This differs from sandbox configuration escape in timing. That entry's defining pattern is a write that outlives a session and is reloaded with elevated trust at a later launch. This entry's defining pattern needs no later reload at all: the command runs during the single apply or provisioning call the declaration was built to trigger, the first time anyone, or any agent, applies it.
Mapping to standards and research
Source | Source-owned term or item | Relationship to this article |
|---|---|---|
chezmoi project (twpayne) |
| Primary source establishing script execution as a documented, intended feature of a declarative dotfile tool's apply step. |
Coder / Cloud Security Alliance (2026-09) |
| Primary-source-corroborated evidence of the same pattern reached through infrastructure-as-code module-registry compromise, with a Critical severity rating. |
SafeDep (2026-06-03) | Miasma worm | Corroborating evidence that AI coding agents already execute repository-shipped automatic setup artifacts without per-file review, the precondition this entry's agent-specific risk depends on. |
OWASP GenAI Security Project | Top 10 for Agentic Applications 2026, | SSA-selected OWASP category for a declaration or input becoming executed code through a tool's own documented invocation path. |
MITRE ATLAS |
| SSA-selected ATLAS techniques for registry- or dependency-level compromise of a declaration, and the interpreter-level execution the apply step reaches. |
Agent State Attack | Target-state script injection | SSA descriptive framing bundling the chezmoi script model, the Coder registry compromise, and the Miasma worm under one Tool & Environment State entry. |
Related terms
- Agent state attack: the umbrella definition, including Tool & Environment State among the listed target states.
- Instruction file poisoning: the adjacent pattern where the poisoned object is a file the agent loads as instructions to itself, rather than a declaration a tool executes as part of reconciling external state.
- Sandbox configuration escape: the adjacent Tool & Environment State entry for writes that outlive a session and are reloaded with elevated trust at a later launch, contrasted above by timing.
- Agent command-approval bypass: a related Tool & Environment State entry concerning a guard approving the wrong representation of a command, rather than a tool whose documented apply step is command execution by design.
FAQ
Is this a vulnerability in chezmoi or Terraform?
No. Neither project has a defect here. chezmoi's script model and Terraform's provisioners and external data sources are documented, intended features; the risk sits in treating a declaration built on top of those features as reviewable configuration rather than as the executable code it actually is once applied. The Coder incident was a registry-infrastructure compromise that substituted a tampered module for a trusted one, not a flaw in Terraform's own provisioner mechanism.
Does an AI agent have to be involved for this risk to exist?
No, the underlying mechanism predates agents entirely; a human running chezmoi apply or terraform apply against a compromised declaration faces the same code execution. What changes with an agent in the loop is scrutiny: the Miasma worm shows agents and the editors wrapped around them already execute repository-shipped setup artifacts without the per-file review a cautious human might apply, and an agent instructed to "bootstrap this environment" or "apply this module" has no inherent signal that the step it is about to run is a code-execution event rather than a configuration sync.
Sources
- chezmoi, Use scripts to perform actions
- Cloud Security Alliance, Research Note: Coder Registry Compromise Spreads Credential-Stealing Terraform Modules (2026-09)
- eSecurity Planet, Coder Registry Compromise: Malicious Terraform Modules Explained
- SafeDep, Miasma Worm Targets AI Coding Agents via GitHub Repos
- OWASP Top 10 for Agentic Applications 2026 (Version 2026, December 2025)
- MITRE ATLAS
- MITRE ATLAS data release v2026.06 (2026-06-30)
Verification and change history
Standards and versions referenced: OWASP Top 10 for Agentic Applications, Version 2026 (December 2025); MITRE ATLAS, data release v2026.06 (2026-06-30).
Last verified: 2026-10-13. The chezmoi documentation, the Cloud Security Alliance research note, the eSecurity Planet article, and the SafeDep Miasma writeup were read from the sources' own pages on this date. The OWASP and MITRE identifiers were selected against this site's previously verified crosswalk entries. The underlying GitHub Security Advisory, GHSA-vx42-ghc9-gw65, is cited by both secondary sources above but did not resolve directly at the time of verification; the Coder incident facts in this article are sourced to the two independent outlets that both reported having read it, not to the advisory page directly.
Change history: 2026-10-13, first version.
Working-term label: Mixed provenance. GHSA-vx42-ghc9-gw65 is a Standard-identified advisory, cited here via independent secondary reporting. "Miasma" is a researcher- and industry-coined name used by SafeDep and other outlets for the campaign described above. ASI05:2026 is an OWASP Standard Term. AML.T0010 and AML.T0050 are MITRE ATLAS Standard Terms. "Target-state script injection" as the umbrella title for this entry is SSA descriptive wording, not a term attributed to any single source above.