Data Report · By Chris Sowa · Published
Last updated
Can a Coding Agent Be Tricked Into Installing a Malicious Package?
Yes, when a dependency arrives as text the agent acts on: a typosquatted, invented or newly registered package runs inside whatever environment the agent works in. Check what the install step can read and where it can send before an agent adds anything to a project.

For a team running a coding agent, an install command begins as a reading decision. The agent opens an issue comment, a pull request thread, a package page or an error message, decides that a dependency belongs in the project, and runs the command, and the package's own script then runs with the reach the agent already has (What Is a Tethered Agent?). Three kinds of package arrive by that route: a name one character away from the real one, a name the model invented and someone registered after the fact, and a legitimate package whose latest release was taken over. The question in the title is therefore two questions: whether the agent can be induced to name the package, and what the package collects once it runs. The first belongs to the text the agent reads and the second to the environment the install inherits. OpenAI, GitHub and Firecracker document the network and the sandbox around an install, and an allowlist, a lockfile or a scoped token each stops short somewhere, so the decision is which control limits what a postinstall script can read.
Key findings
- A study of agentic coding editors found that "attack success rates can reach as high as 84% for executing malicious commands," a measure of how often text an agent read became a command it ran (Liu et al., Your, 2026).
- Code generating models invent package names: "the average percentage of hallucinated packages is at least 5.2% for commercial models and 21.7% for open-source models," and a name that does not exist is a name someone else can register (Spracklen et al., 2025).
- Sonatype reported that "56% of the malware discovered in Q1 2025 was related to data exfiltration," "a dramatic increase from 26% in Q4 2024," which is the purpose a postinstall script serves (Sonatype, 2025).
- OpenAI's cloud documentation states that "By default, Codex blocks internet access during the agent phase," so an install's own network calls depend on a setting the team chose (OpenAI, Codex Cloud, 2026).
- A governed environment replaces values with tokens before any model reads the screen, so the comment, the package page and the error message that shape a dependency arrive as text with placeholders where the credentials sat (What Is Least Exposure?).
- Real values resolve only at the approved destination at the moment of an approved action, so a run that installs the wrong package leaves a value that reached one named destination and a record of every screen the model was shown (What Is Least Exposure?).
What does a browser control cover when the install runs in a terminal?
The install itself is a command in a package manager, and that command runs in a terminal, a build runner or a CI job. A governed browser environment covers the pages an agent reads and acts on: dashboards, consoles, settings pages and sign-up forms. It does not cover the terminal, the IDE, the local filesystem, direct API calls or MCP. The two halves of an install sit on opposite sides of it.
The reading half is inside. Before any command runs, the agent opens a page: the issue thread where a colleague wrote that a package was worth trying, the registry listing for a package, the repository page for a dependency. Whatever those pages render is what the model receives, which makes the suggestion a document rather than a conclusion.
The running half is outside. The install command is a terminal action, and the script that ships inside the package runs with the same environment the command had. OpenAI's local-agent documentation states that "Locally, Codex uses an OS-enforced sandbox that limits what it can touch (typically to the current workspace)," a boundary on where the agent writes rather than on what an install reads (OpenAI, Agent, 2026). A workspace boundary does not decide which host a script talks to, and it does not empty the environment the script starts with.
The example this page returns to is a record type: a dependency whose postinstall script reads the job's environment variables and then makes one outbound request. Every section below asks the same two questions of that record. What did the agent read when it chose the package, and what could the script reach when it ran?
How does a malicious package get chosen in the first place?
The first route is the near miss. A name one letter or one plural away from the package the agent meant sits in a comment, a blog post or a readme, and the near-miss name belongs to a different package with a different publisher. Nothing in the install command distinguishes the two, because the command is only a string.
The second route is invention. Code generating models invent package names: "the average percentage of hallucinated packages is at least 5.2% for commercial models and 21.7% for open-source models," and a name that does not exist is a name someone else can register (Spracklen et al., 2025). The study does not say whether any hallucinated name was registered and installed, so the finding is a rate of invention, not a count of campaigns.
The third route needs no trick at all. A legitimate package with a hijacked maintainer account or release pipeline is installed by an agent that did what a careful person would have done.
Bad packages are abundant. Datadog reported that "Throughout 2024, Datadog identified thousands of malicious PyPI and npm libraries in the wild," so the supply of a bad package is not the constraint (Datadog, 2025).
What turns a supply into an install is the reading. The benchmark literature is candid that defense is measured rather than settled: "we conduct a systematic evaluation on 5 prompt injection attacks and 10 defenses with 10 LLMs and 7 tasks" (Liu et al., Formalizing, 2024). None of those defenses is the package manager, and none of them is the review a person would do before adding a dependency. The agent's substitute for that review is a page.
What do the vendors themselves say?
Three vendors document the part of this problem each owns.
OpenAI's cloud documentation states that "By default, Codex blocks internet access during the agent phase," so an install's own network calls depend on a setting the team chose (OpenAI, Codex Cloud, 2026). The same page states that "Setup scripts still run with internet access so you can install dependencies," which places the install step outside that block and lists prompt injection from untrusted web content as a risk of turning access on, with advice to allow only the domains and HTTP methods the task needs (OpenAI, Codex Cloud, 2026). The local page states that "By default, the agent runs with network access turned off" and that "Codex asks for approval to edit files outside the workspace or to run commands that require network access" (OpenAI, Agent, 2026): destination controls, with nothing on how a credential is stored in a local session.
Firecracker's design documentation states that "Firecracker is designed to assure secure isolation using multiple layers" and that "All egress traffic from a guest is therefore considered untrusted, and should be filtered at the host-level"; its subject is the boundary between guest and host rather than the contents of the guest (Firecracker, 2026).
GitHub's Actions security reference states that teams should "Pin references to actions to a commit SHA in your workflow files," the same pinning logic a lockfile applies to a package (GitHub, Secure, 2026). None of the three documents a control on what the package's script reads once it runs.
| Dimension | OpenAI, per its documentation | GitHub, per its documentation | What a buyer should verify | |---|---|---| | Default network state | Blocked during the agent phase in the cloud; off by default locally | The runner's egress belongs to the workflow and the platform | Whether the install step runs in the phase that is blocked | | Install step | Setup scripts run with internet access | A job installs from a registry as the job | What the setup or job phase can reach | | Sandbox | OS-enforced, typically to the current workspace | Ephemeral environment for the agent's job | Whether the boundary limits destination or only location | | Credentials | Not described as stored or handled in a local session | Token scope and lifetime are settings | What the install step inherits | | Version pinning | Not the subject of the cloud page | Actions pinned to a commit SHA | Whether the dependency version is pinned the same way |
What can a postinstall script read once it runs?
Take the example record. A package's postinstall script runs after its files are unpacked and before anyone reads its source, as the user that ran the install, so it inherits the job's environment variables, working directory and network position. It does not need a token inside the package; it reads what the job holds.
A job holds more than the task needs. Two GitHub settings bound how far a token reaches, and neither removes it. GitHub's token page states that "Each token can be further limited to only access specific repositories for that user or organization," which limits reach without removing the token from the job (GitHub, Managing, 2026). It also states that "Infinite lifetimes are allowed but may be blocked by a maximum lifetime policy set by your organization or enterprise owner," so an expiry is a setting a team chooses and can leave unset (GitHub, Managing, 2026).
The identity an action runs under decides what it can reach: What Can Microsoft Copilot Studio Agents See? records agent author authentication where access is implicit and user authentication where it must be restricted to specific groups. An installer makes no such choice. It runs as the job.
The pages an agent opens are worth as much as the token: What Can an AI Agent See in Your GitHub Settings? records that GitHub tells users to treat access tokens like passwords, which does not change what a script finds.
Do an allowlist and a lockfile make the install safe?
Each control answers one property of the install.
A registry allowlist answers where the install may talk. It is the advice OpenAI gives for the agent phase and the filter Firecracker asks for at the host level. It does not answer what the install may read, and it treats every package on an approved registry as approved code.
A lockfile or a pinned commit answers which version runs. It closes drift and a registry that serves a different build, and the pinned version still runs, the same logic GitHub's Actions reference applies when it asks for a commit SHA instead of a tag.
Token scope and lifetime answer how far a stolen value reaches. Scope is worth setting, and the survey above shows how often it is not: the same Datadog survey found that "37 percent of customers who send CloudTrail logs to Datadog are using IAM users in their GitHub Actions," a sign of how often a workflow holds a long-lived key (Datadog, 2025). A durable key is one a script can use for as long as it likes.
A sandbox answers where the agent writes, the right control for a different question.
None of the four answers what the model read before it proposed the install. A pipeline can authenticate without a stored key, the arrangement How to Set Up S3 and GitHub With Cowork or Dots describes, and the install still runs as the identity it obtained. Is It Safe to Let an AI Agent Set Up Your Cloud Environment? records AWS advice against creating access keys for the root user, the durable credential a script would most like to find.
What does a governed environment change?
A governed environment is a control class that acts where a page is rendered, before any model reads it. Values chosen by policy are replaced with consistent tokens for the whole run, so the model works on placeholders such as GITHUB_TOKEN_01. Real values resolve only at an approved destination, at the moment of an approved action. A named person confirms the tokenization policy and approves each consequential action, and a dependency change is one. Every screen as tokens, every action and every approval is written to a record that exports to the organization's own monitoring.
For this page's question it changes three things. The text that becomes a suggestion arrives with the values already replaced, so a comment pasted from an attacker's page cannot put a live credential into the context. A value that escapes through a page has nowhere to resolve except the destination a person approved, the difference between a script that collects a token and one that collects a token that works. And the record answers what the agent read before it proposed the install, the question an allowlist, a lockfile and a sandbox leave blank.
It does not change the package. Whether a name belongs in the project stays with the registry allowlist, the lockfile, the sandbox and the person who reviews the change. A correct permission check is not exposure control: Microsoft's posture management documentation states that generative AI amplifies the problem of oversharing data, so exposure is real even when the permission check is correct (Does Microsoft Copilot Expose Sensitive SharePoint Data?).
It does not govern the install command, only what the agent read on the way to proposing it.
Methodology and limitations
This page rests on three research preprints on agentic coding editors, package hallucination and prompt injection benchmarks, on vendor documentation from OpenAI, GitHub and Firecracker, on one GitHub security reference, on two industry research posts from Sonatype and Datadog, and on existing RedactSure research pages. Vendor pages were read as of October 20, 2026, and each Sources line carries the date for its page. Research figures are quoted from the abstract pages as recorded, and whether any hallucinated package name has been registered and then installed is left open because those pages do not answer it.
RedactSure did not install a package in a test environment for this page, and no named product was tested hands-on. Where the text says a vendor does not describe a behavior, that means the pages reviewed do not record it, which is not a statement about what the product does. Vendor features change and the page carries its date, so a release after that date should be treated as unreviewed until the same questions are asked of it. The two research posts are vendor research, drawn from the vendors' own telemetry and customer samples, and are cited for the scale they report rather than as an independent measurement. Statements about RedactSure describe current design, and RedactSure is deploying now with enterprise and government customers. The example describes a record type, a dependency whose postinstall script reads its environment, and not an organization.
Determinations about whether an install flow meets a contractual, licensing or regulatory requirement belong to counsel, assessors and the organization's own security and compliance officers. Nothing here replaces a test of the organization's own agent against a throwaway package and a token issued for the test.
What the record shows
A coding agent adds a dependency from text it read, the package's script runs with the environment the job holds, and the controls that vendors document bound the destination, the workspace and the token rather than the script's reach. An allowlist and a lockfile are both worth having, but the allowlist is not sufficient and the lockfile runs the same code. A scoped, short-lived token is the control that changes what a successful install collects, because it is the only one that limits what a stolen value can do afterwards. A governed environment adds the reading half, with tokens in place of values before the model reads a page and a record of what it read; RedactSure builds that environment. Writing down three things for one agent and one dependency suggestion is a fair test for a team: the page the suggestion came from, what the install step could read, and which destination it could reach.
Frequently asked questions
Can a coding agent be tricked into installing a malicious package?
Yes. The agent acts on text: an issue comment, a readme section, an error message or a registry page. A name one character off, a name the model invented, or a legitimate package with a hijacked release can all arrive that way, and the install runs the package's own script with the reach of the job. A dependency is a small decision with a large blast radius. The defense is not a better prompt. It is a narrower environment, a pinned version and a destination list.
What is a postinstall script, and why does it matter here?
It is code that a package runs automatically after its files are unpacked, before anyone reads its source. It runs as the user that ran the install, so it inherits the environment variables, the working directory and the network position of that job. The script is why an install is a security event. That is how a package chosen from a page reaches a token no page ever showed, and why the environment around an install matters more than the wording of the request that started it.
Does an allowlist stop a malicious package?
It limits where the install can talk, and that is worth having. It does not decide whether a package is malicious, because a malicious package on an approved registry is still on an approved registry. It also does not limit what the script reads before it tries to connect. An allowlist is a network rule, and the package manager is not a network. Read it as a destination control, pair it with a version pin, and let a short-lived token limit what a successful install would collect.
Does pinning a version or committing a lockfile help?
It helps with drift and with a registry that serves a different build than the one a reviewer saw. The pinned version still runs, and a lockfile cannot cover a name that was registered after the model suggested it. Pinning is the logic GitHub applies when it asks for a commit SHA instead of a tag: it fixes what runs, not what running code can read. A lockfile records a decision; it does not sandbox the code that decision allows.
What should I take out of the environment before an agent installs anything?
Long-lived credentials first: a token with no expiry, a cloud key, a registry password the job does not need. Scope what remains to the repositories the task touches and give it an expiry, because both are settings a team chooses. Then look at the install step separately from the agent phase, since a paused agent and an open setup script are two postures on the same machine. Anything the install does not need is a liability it can reach.
What is the one question to ask a vendor?
What does the install step receive, and where can it send it? A document that answers with a destination list and a token lifetime has answered the second half. The first half is what the model was shown when it chose the package, and few documents address it. Ask for the pages the agent read on the way to the suggestion, then run one install with a token that exists only for the test. The answer should name a page and a value, not a policy.
How RedactSure Keeps a Malicious Install Out of the Credential Path
An agent adds a dependency because a page told it to, and an allowlist or a lockfile narrows destinations and versions without changing what an install can read.
The environment that enforces this is built by RedactSure, an AI agent controls, governance and data protection company.
Before: the issue comment that names a package and the page that describes it render as text, and a code sample prints the workspace token, so the command carries a live value. Inside: the sample shows GITHUB_TOKEN_01 and the dependency change waits for a named reviewer; the real token resolves only for the destination that reviewer approved.
RedactSure is deploying now with enterprise and government customers. The agentic editor study put command execution at up to 84% attack success.
Everyone else controls where data can go. RedactSure controls what the AI can see.
See it on your own workflow
A malicious package can carry out whatever live values the command holds. Bring a dependency change your agent already makes and see, with test values, what the command would carry and who approves the change. Book a demo








