CVE Index中文
L4 · Septic Tank BlewGitHub Actions · CI/CD · credential theftwfx-phantom-github-actions

WFX Phantom uses stolen GitHub tokens to run a CI credential stealer

Attackers used stolen developer and bot tokens to plant a shell stealer in GitHub repositories, then reverted commits and deleted runs. The stealer can collect runner memory and exchange OIDC tokens for cloud access. Newer samples upload through Telegram.

Disclosed
Nov 11, 2026
Public disclosure date
Severity
Septic Tank Blew
No CVE: a breach, not a bug
Splash zone
GitHub repositories writable by stolen developer or bot tokens, where the injected workflow, script or package hook can run.
GitHub Actions · CI/CD · credential theft
In the wild
Yes
StepSecurity observed execution. WebdriverIO recorded unauthorized bot commits.

What happened

The campaign requires a valid token with repository write access and a path to execute the code. It modifies an existing workflow, creates a new workflow, appends to a script CI already calls, or adds a hidden script and hooks it into an npm lifecycle or build/test command. Workflow variants can explicitly pass secrets to the script. Script variants can read runner memory and credential stores when the job has access. Cloud escalation depends on the runner’s credentials and the permissions and trust attached to them. Required-check forgery exists in the payload but was disabled in the samples StepSecurity examined.

StepSecurity found some probe PRs attributed by GitHub to Fly.io’s GitHub App and identified the credentials as user-to-server tokens. It did not establish how they were obtained or find evidence of compromise of Fly.io infrastructure. The research identified overlaps with October GhostAction without attributing both campaigns to one actor.

Nextcloud Docker’s run 2675 executed the injected commit on a self-hosted runner and finished successfully. StepSecurity interpreted the log as evidence of a successful upload. The log does not enumerate the contents of the uploaded archive.

Release artifacts to check

  • Packagist digitalelvis/neuronai-studio 3.14.3 contains the script and npm postinstall hook. The hook can execute if npm installs dependencies in the package directory with lifecycle scripts enabled. Composer does not invoke it on its own. StepSecurity recommends pinning 3.14.2 or earlier.
  • Go module github.com/onuragtas/docker-env v1.0.278 and v1.0.280, and github.com/vkuznet/gocurl v0.0.0-20261111095532-8d5aad0cb0da, carry the payload in workflow files. Normal Go builds do not execute GitHub workflow files. Check go.mod and go.sum, including direct and transitive dependencies, and replace those versions with independently verified inputs.
  • StepSecurity reports no affected WebdriverIO package release. Verify other releases produced between an injected commit and cleanup using clean source and build records.

Indicators to correlate

  • HTTP endpoints at 194.150.166[.]244:8080/exfil, 18.143.168[.]96:8080/exfil and 153.75.82[.]159:8080/exfil. The older 193.32.204[.]199 endpoint was still present in some previously implanted GhostAction workflows. HTTP callback values included b42d70a7aab9140ca19e8249 and 15f44heehnax8jdf41yx.
  • Telegram api.telegram.org with sendDocument, chat -1004340163187 and bot IDs 8708988906, 9196217635, 9180059428, 8902935164, 8876515636. Telegram-only samples set the HTTP callback to loopback.
  • Probe PR docs: dependency audit notes, body Routine dependency audit notes, branch wfx-docs, file docs/wfx-audit.md and blob ee6e5addfe591923fc385553cb66cf0d25634a6b.
  • Commit messages ci: refresh build cache, ci: restore, ci: cleanup, chore: add ci helper, chore: add dependency audit workflow, and chore: initial commit before the workflow in empty repositories.
  • Branch patterns chore/[a-z0-9]{8} and ci-check-[0-9]{4}; paths matching .ci-[a-z0-9]{6}.sh and .github/workflows/build-audit-[a-z0-9]{6}.yml, or changes to existing workflow files, shell scripts or package.json.
  • Steps Pass runtime, Restore cache <4 characters> or Run audit; variables WF_CALLBACK, WF_CTOKEN, WF_EXFIL_*, WF_TG_BOTS; staging path .wfx-$$; log strings memscan_files, archive_bytes, deliver_retry.
  • Azure federated credentials named wfx-ci-*; AWS trust changes granting a wildcard AWS principal, and AWS sessions named wfx-*.

Crime-scene timeline

  1. Nov 10, 2026

    StepSecurity dates the start of the campaign

    Stolen GitHub tokens are used to probe repositories and push malicious changes.

  2. Nov 11, 12:30 UTC

    WebdriverIO contributor publicly documents two malicious bot commits

    The commits hook postinstall. Later the same day, a surviving Nextcloud Docker workflow log documents execution of another variant.

  3. Nov 12, 01:10 UTC

    Telegram appears as a backup in one sample

    The sample also points to a third HTTP collector.

  4. Nov 12, 2026

    StepSecurity publishes its campaign analysis

    It saw Telegram-only delivery from about 05:30 UTC and reported over 63,000 probe PR search results at 07:40 UTC. The search count does not measure successful compromises.

Who said what

We list each claim and who made it. Primary sources (the vendor, the researcher, the registry) are marked. Where reports disagree, we grade by the worst credible case.