BlackTree Security · Infrastructure · Automation · AI

GhostAction Hid a Credential Harvester Inside a Security Audit

Deleting the workflow is not enough. GhostAction also searched reachable Git history for cloud, platform and AI credentials.

StepSecurity says compromised maintainer accounts pushed security-audit.yml into 345 repositories on 8 October: 27 from about 13:20 UTC and 318 from 21:10 to 21:26 UTC. In uber/athenadriver, the collection server acknowledged a request within four seconds. This confirms outbound delivery, not the number of usable secrets.

The evidence points to compromised maintainer credentials, not a compromise of GitHub’s platform. The injected commits used the maintainers’ identities and went directly to default branches. The practical incident boundary therefore includes both the repository and the account authority that allowed the workflow to be written.

The history changed the response

Using a full-depth checkout, the workflow searched the working tree and reachable commit diffs with credential patterns and output caps. It targeted AWS, GitHub, GitLab, Google, Firebase, Slack, SendGrid and AI-provider keys. Credentials removed from the current tree could still be exposed, but the method could not guarantee complete historical recovery.

That makes a routine clean-up incomplete. Removing the workflow stops another run, but it does not invalidate anything already offered to the collector. Rotating only the secrets currently configured in Actions also misses credentials that once appeared in another branch, tag or historical diff.

The one-repository difference is scope

StepSecurity counts 345 repositories in the two compromised-account sweeps. Socket counts 346 workflow files: 318 under henrywoo, 27 under kitao and the Uber-owned uber/athenadriver repository separately. The difference is an inclusion rule, not a second burst or an extra confirmed theft.

Neither total is a count of repositories that definitely held a valid secret. The successful collection acknowledgement in uber/athenadriver establishes outbound delivery for that run, but it does not disclose the request body or prove that every other injected workflow executed.

Contain the account, then rebuild trust

  1. Revoke the injection path. Invalidate active sessions, personal access tokens, OAuth grants and SSH keys for the affected maintainer account. Review its audit history and every repository it could write to.
  2. Remove every copy. Delete security-audit.yml, github_actions_security.yml and security-check.yml from affected branches and repositories. Inspect forks before treating removal as complete.
  3. Establish execution. Review Actions runs from 31 August onward and runner connections to 193.32.204.199 on ports 80 or 3000. Search for AKIA_CTX_START, ?c=monami and ?c=new.
  4. Build a history-based rotation list. Perform a full-depth credential scan across reachable branches and tags. Rotate current Actions secrets and matched cloud, source-control, SaaS, AI-provider and publishing credentials from a known-clean system.
  5. Protect the release boundary. Pause releases until publishing credentials and recent artefacts have been checked. Require reviewed workflow changes, narrow write authority, use approvals where practical and restrict runner egress.

This response is broader than the credential rotation used for an ordinary CI secret leak. It treats repository history as an exposure inventory and maintainer authority as a production control. BlackTree has previously examined why valid provenance cannot repair a weak workflow authorisation boundary and why push access can become publish access. GhostAction begins one step earlier: the attacker uses trusted account authority to install the collector itself.

Evidence boundary

StepSecurity published on 9 October without a displayed time and had not observed malicious package releases from the exposed publishing credentials as of writing. That observation did not make credentials safe.

GitGuardian published on 7 October and added a Socket-attributed update on 9 October; no update time is displayed. Socket displays 9 October; its update shows a literal [HH:MM] UTC placeholder. The original mechanism used to obtain each maintainer credential remains unconfirmed. No CVE is associated with this campaign.

Sources

Leave a Reply

Your email address will not be published. Required fields are marked *