The command was called aipoison
Socket found a cluster of 18 npm packages impersonating Alibaba's private @ali scope. None of the tarballs contained malware. The RAT assembled itself at install time out of a JSON file in a GitHub repo the attacker still controls, and its persistence plan included patching Python inside the .skills directories of AI coding tools, using commands named aipoison, aipoison_inject, and aipoison_deploy. Reading the code could not have found this. Bromure Agentic Coding judges what was visible all along: a package with no reputation pauses for your consent at the host proxy, the three fetches that assemble the payload hit a wire that only speaks to destinations you approved, and every file the RAT writes lands in a VM that lives for one task.
Somewhere in the final payload is a command named aipoison. Its job is
to reach into the skills directory of your AI coding tool and patch a
Python file, so that the next time you start work, the attacker starts
too.
On August 3, 2026, The Hacker News
covered research Socket published in late July:
a cluster of about eighteen npm packages, staged in late April, that sat on
the registry for three months before anyone caught them. They impersonate
Alibaba's private @ali-scoped packages by publishing the same names
unscoped (aone-cloud-cli, def-open-client, open-worker-cli,
uniapi-bridge), so a developer or a build inside the target organization
resolves the public lookalike and gets a remote access trojan grafted onto
the dependency tree. Socket's researcher Karlo Zanki reads the motive as
industrial espionage.
Nothing in the packages was malicious
Open any one of those tarballs and you find nothing to report. There is no
postinstall hook, the first thing anyone greps for. The lure packages
depend on smart-config-manager, which depends on cloud-config-fetcher
and local-config-parser. A config manager, a fetcher, a parser: boring
utilities, each legible in a minute.
The malice lives in the composition, and in a file the attacker never
shipped. On import, the fetcher downloads defaults/preferences.json from
a GitHub repository the attacker controls, and still controls, then writes
it to disk as .cloud-preferences.json. The parser evaluates that file's
"transform rules" inside a Node vm, which is where the attack lives. One
rule is a sandbox escape with folklore status:
var F = items.constructor.constructor; // recover Function
var p = F('return process')(); // recover process
From process it walks a fallback ladder (getBuiltinModule,
mainModule.require, mainModule.constructor._load) until one of them
yields require on whatever Node version it landed on. Then it fetches
setting.js from an Alibaba Cloud storage bucket, which fingerprints the
host and installs the payload: on Windows, kill Alibaba's own Alilang
security app and replace its app.asar with a trojaned copy; on Linux,
drop a binary in /tmp, run it detached, delete the file; on macOS, inject
into ~/.zshrc and register a LaunchAgent that fires every ten minutes.
GBHackers put the design in its headline: attackers split the RAT across packages to evade isolated code reviews. The attacker built this campaign to survive someone reading it. Review any package on its own and it passes. Review the whole tree and it still passes, because the hostile part is a JSON file on a server, fetched after you finished reviewing, editable by the attacker between your audit and your install.
The persistence plan has your agent in it
Socket recovered the final payload as aone-cli. It does what these things
do: shell commands, file upload and download, host recon, screenshots, an
encrypted reverse TCP proxy, and a dws_lateral command that moves through
DingTalk. Its C2 traffic wears forged Origin and Referer headers
claiming to come from an internal Alibaba docs domain.
One group of commands makes this a coding-agent story. Alongside the usual
verbs, the RAT ships aipoison, aipoison_inject, and aipoison_deploy.
They patch Python scripts sitting in the .skills directories of specific
developer tools, marking the injected snippet with # __INJECT_MARKER__,
so a script pulled from C2 runs later, from inside the tooling, as you.
Among the named targets is
Qoder,
Alibaba's own agentic IDE, which passed five million users within months of
launching last August.
Someone sat down, looked at the modern developer machine, and picked the
agent's skills folder as the durable foothold: a directory of scripts that
runs with your permissions at the start of every session, and that few
people ever diff. We have watched this move before, when a worm copied
itself into .claude so the next agent
start would reinfect the machine. It has graduated from a worm's improvised
trick to a named command in an espionage toolkit.
The parts the attacker could not hide
Reading the code was never going to find this. The attack still had requirements, and all of them were visible: a package with no history and no reputation, three outbound connections before it could act (the GitHub rule file, the cloud-storage stage, the C2), and a machine that would still be there tomorrow.
Bromure Agentic Coding puts a decision on each of those, and makes it on your Mac, outside the box the agent runs in, where nothing inside can argue.
The install pauses at the registry. Every package fetch crosses the
host-side proxy, which applies your workspace's supply-chain policy to the
response before a byte reaches the VM. Turn on package filtering and the
proxy consults a reputation provider on each artifact. One of the two
selectable providers is Socket, whose research this post is about. When no
enabled source can vet a package, the proxy holds the download and asks
you. Lookalikes of a private scope, published last quarter with a handful
of downloads and no reputation anywhere, stop there. Enforcement sits on
the host by design: the .npmrc inside the VM can tighten the policy and
cannot loosen it, so the rule holds even when the compromised thing is the
thing doing the policing.
The wire refuses the assembly. This design breaks against egress
consent, because with nothing hostile in the tarball, the network is the
attack. The host proxy checks each of the three fetches (the attacker's
GitHub raw file, the storage bucket serving setting.js, the C2 host)
against the destinations you approved for this profile. The registry you
install from is on that list. A stranger's raw-content path and a bucket
named after a CLI you have never heard of are not. The proxy has no opinion
about items.constructor.constructor and needs none. It reads the
destination, finds nothing approved, and drops the connection. Your install
finishes, your build runs, and the RAT never assembles, because its parts
never reach the same room.
Persistence gets a machine with a lifespan of one task. Suppose the
whole chain runs anyway, because you approved a destination wider than you
meant to and the stages land. The ~/.zshrc line, the ten-minute
LaunchAgent, the trojaned app.asar, the patched .skills Python: all of
it writes to a disposable Linux VM, one hypervisor away from macOS, holding
this task's workspace, and you throw the VM away when the work merges.
aipoison is a bet that the tooling it patches and the host it compromised
are the same long-lived machine. In a profile, that bet loses. The recon
that runs first comes back with broker
decoys: your real credentials live on
the host and get injected at the wire only for approved destinations, so
they were never in the VM to
collect.
Reviewing an artifact tells you about the artifact
Researchers keep re-teaching this lesson in a different library every week. Yesterday a trust flag fell because the check and the load happened at different moments. In June, a repository stayed clean because the reverse shell lived in a DNS record. Now eighteen packages read clean because the malicious part is a JSON file the attacker is still holding.
Agents sharpen this, because they are fast. An agent asked to wire up an internal API adds the dependency, runs the install, and moves to the next step of the task in the time it takes you to switch windows. That speed is the whole reason you bought it. Put the judgment where the speed cannot outrun it: at the registry fetch and at the wire, where your Mac decides against a policy you set once, for every package and every connection the agent makes.
Keep letting the agent install things, because that is where the leverage is. Install Bromure Agentic Coding, turn on the supply-chain layers, and give the profile a list of destinations that make sense for the work. The next campaign will hide its payload somewhere else, the one safe prediction in this business, and it will still have to fetch it across a wire that asks you first.