All posts

    Agent security

    wfx-loot: 4,837 hijacked GitHub accounts push a CI secret stealer, AI tokens included

    An attacker used stolen GitHub tokens to push a CI secret stealer that takes AI provider and tool tokens along with CI secrets. Here's who's exposed and what to rotate and check this week.

    Harden

    Executive summary

    On Nov 10, an attacker started using stolen credentials from 4,837 GitHub accounts to probe 61,764 repositories. Next it pushed a shell script of about 1,500 lines that steals CI secrets and AI provider and tool tokens, and it can leave persistence behind in AWS and Azure. Aikido says the script ran in at least 1,835 repositories. This post covers who's exposed, what to rotate and check, and where a laptop-side control helps and where it doesn't.

    What happened#

    On Nov 10, an attacker started using stolen credentials from 4,837 GitHub accounts. With them, it opened probe pull requests in 61,764 repositories, according to Aikido Security.

    Next it pushed a shell script of about 1,500 lines into CI. The script steals CI secrets and AI provider and tool credentials (OpenAI, Anthropic, Gemini, Hugging Face, Cursor, Copilot and others). It sends them out by HTTP POST to 2 IP addresses on port 8080.

    After that it cleans up. The attacker reverts the commit within about a minute and deletes the workflow run and its logs.

    Aikido says at least 1,835 repositories ran the script. SafeDep counted something different: 8,093 repositories that received malicious commits between Nov 10 at 12:46 UTC and Nov 12 at 04:36 UTC. Probes, commits and executions are separate counts, so don't add them together.

    The payload also leaves a way back in. It can rewrite an AWS role's trust policy and add Azure federated credentials named wfx-ci-…. Rotating the stolen secrets removes neither. Quincy Castro at Chainguard reported that the campaign was still active on Nov 12.

    Who is affected#

    The attacker signs in with valid stolen tokens. That puts any repo with workflows at risk if one of those accounts could push to it.

    If a probe PR from one of these accounts shows up in your repo, treat that account as compromised, even if nothing ran.

    What's at risk is whatever the workflow could reach: repo secrets and variables, the cloud roles it assumes, and the AI provider keys your agent workflows use in CI. If no compromised account could push to a repo, the push stage didn't touch it.

    There's a package angle too. Aikido lists Packagist digitalelvis/neuronai-studio 3.14.3. SafeDep says a normal composer require or go get doesn't run the payload, but npm install inside the vendored Packagist package does.

    What to check this week#

    • Get the indicators (probe branch name, PR title, commit messages, the 2 exfiltration IPs) from Aikido's write-up. Search every repo and your org audit log for them.
    • Look for gaps in workflow run numbers since Nov 10. Deleted runs leave gaps in the sequence.
    • For any account linked to a probe, revoke its tokens, OAuth grants and SSH keys, then enforce 2FA.
    • If the payload may have run, rotate every secret and variable the workflow could read, AI provider keys included.
    • In AWS, check for role trust policies changed since Nov 10 and access keys nobody on your team created.
    • In Azure, check app registrations for federated credentials whose names start with wfx-ci-.
    • Block egress to the 2 IPs and keep the logs.
    • Find developers who ran npm install inside the vendored digitalelvis/neuronai-studio package and treat those machines as compromised.

    SafeDep's write-up doesn't describe any action by GitHub. For now, branch protection, required reviews and short-lived fine-grained tokens limit what one stolen token can push.

    Where Harden helps, and where it doesn't#

    Harden Agentic Integrity Foundation (AIF) runs on the developer laptop, outside the agent, at the agent's pre-execution hook. It checks every command, file edit and push against the session's intent before it runs. Decisions are made locally, in milliseconds. One policy covers every agent, and it starts watch-only.

    In this story, it helps on the laptop. Say an agent tries to read a token or credential file and send it over the network. Harden follows the secret from where it came from to where it's going and stops that flow before the command runs. It also checks a push that edits a workflow nobody asked for.

    It wouldn't have caught this campaign itself. The stealer runs as a workflow on a GitHub runner, not through an agent on a laptop, so Harden never sees it. It can't undo a token that's already stolen or remove persistence in AWS or Azure. And it doesn't replace scoped credentials, egress policy or branch protection.

    If you run agents in CI, the secrets they hold are the prize. Least privilege and short-lived credentials do more there than anything on the laptop.

    Read more#

    For the laptop side, see how to stop coding agents leaking secrets.