William OGOU Cybersecurity Blog

Published

- 6 min read

Mini Shai-Hulud Returns: Poisoned GitHub Actions Re-Enabled

img of Mini Shai-Hulud Returns: Poisoned GitHub Actions Re-Enabled

No new exploit. No new infrastructure. No new compromise. Just two repositories flipped back to public and thousands of CI pipelines started running malware again.

On September 16, 2026, actions-cool/issues-helper and actions-cool/maintain-one-comment became downloadable again, four months after being disabled for the May 2026 Mini Shai-Hulud campaign. Their release tags were never cleaned up and still pointed to the malicious content introduced on May 18. Every workflow referencing them by version tag resumed executing the payload on its next run. Both were disabled a second time on September 25 but if you ran on a tag in that window, assume compromise.

Visiting either repository now shows: “Access to this repository has been disabled by GitHub Staff due to a violation of GitHub’s terms of service.”

What to Remember

  • Reactivation, not reinfection: the malicious code sat untouched since May 18. Re-enablement between 11:09 a.m. and 6:16 p.m. GMT+2 on Sept 16 was enough to restart the attack.
  • Blast radius: GitHub’s dependency graph lists ~15,000 dependent repositories for issues-helper alone, plus maintain-one-comment consumers.
  • Fast burn: these housekeeping workflows run on daily schedules or on every issue/PR event, so most affected repos likely executed the payload within a day with zero action from the attacker.
  • SHA pinning is the fix: workflows pinned to a full commit SHA predating May 18, 2026 were never affected. Tag references like @v2.2.1 resolve to whatever the tag points to right now.
  • Treat Sept 16+ tag runs as breached: rotate every secret the workflow could access and review run history for the telltale seconds-to-minutes duration jump.

Disabled in May, Still Malicious in September

The May 18 compromise gave the threat actor control over what both actions’ release tags resolved to. Socket linked the activity to the Mini Shai-Hulud cluster via the exfiltration domain t.m-kosche[.]com, shared with the @antv npm packages. GitHub’s response was to disable both repositories on May 19 one day after the malicious content landed.

Disabling worked as containment: the Actions runner could not fetch the code, so downstream workflows failed in the Set up job step with Error: Repository access blocked before any action code ran. But disabling is not cleanup. The malicious tags stayed in place the entire time, and re-enabling the repositories removed the only barrier.

Socket could not determine why the repos were re-enabled a legitimate maintainer request is one unconfirmed possibility. The key point stands: containment without cleanup is a reactivation waiting to happen.

What Changed on September 16: the Run Logs Tell the Story

Run histories show the exact moment of re-exposure. A “Close Inactive Issue” workflow failed in 2 seconds at setup before Sept 16; the next run (#1850) took 11 minutes 25 seconds. The runner resolved actions-cool/[email protected] to commit a0c53dd containing the obfuscated payload in index.js, installed Bun via oven-sh/setup-bun, and executed bun run $GITHUB_ACTION_PATH/index.js a multi-minute detour no issue-housekeeping action has any legitimate reason to take.

The pattern repeats on schedule: the Moonofweisheng/wot-design-uni “Issue Inactive” workflow failed in 8 and 5 seconds on Sept 14–15, then succeeded in 9m 34s on Sept 16 at 18:16 GMT+2. A scheduled workflow going from seconds-long failures to minutes-long successes with no change to its own code means its dependency came back online malicious.

Why Tag References Were Hit Again

  1. Tags are mutable pointers, not versions. uses: actions-cool/[email protected] names a Git tag. Whatever that tag points to at job start is what runs.
  2. The runner fetches and executes on every job. At setup, it downloads each referenced action as a tarball and runs it with the workflow’s GITHUB_TOKEN and exposed secrets.
  3. Triggers are routine and often attacker-reachable. Issue and comment workflows fire on schedules or on issue/PR events any GitHub user who can open an issue on a public repo can trigger one.
  4. The payload harvests CI credentials. The May payload steals sensitive credentials from the runner environment and exfiltrates them to attacker infrastructure, consistent with the Mini Shai-Hulud credential-theft playbook.

Remediation: 6 Steps, in Order

  1. Find every reference across all your repos
grep -rn "actions-cool/issues-helper@\|actions-cool/maintain-one-comment@" .github/workflows/
  1. Treat any tag reference as affected @v2.2.1 or any other tag.
  2. Remove the actions or pin to a known-clean full SHA predating May 18, 2026 after verifying the commit content yourself.
  3. Rotate all exposed secrets for any workflow that ran on a tag reference on or after Sept 16, and scope-review what the job’s GITHUB_TOKEN permissions allowed.
  4. Review run history: look for runs that start succeeding after a stretch of Set up job failures, durations jumping from seconds to minutes, or oven-sh/setup-bun / bun run $GITHUB_ACTION_PATH/index.js in runner logs.
  5. Audit for unexpected commits from Sept 16 onward, and pin all third-party actions to full SHAs going forward this incident proves a mutable tag can be compromised, contained, and reactivated without a single change to your workflow file.

Conclusion

Most supply chain incidents involve something new. This one involved nothing new and that is the lesson. A disabled repository is contained, not clean. Platform teams should treat re-enabling a compromise-disabled repo as a high-impact decision: verify tags, releases, and default branches first, and weigh how many downstream workflows will resolve those references the instant it returns. Consumers cannot control that decision, but they can remove the dependency on it entirely with SHA pinning.

This is the same Mini Shai-Hulud cluster behind the TeamPCP worm that hijacked TanStack and the Megalodon commit flood now demonstrating that dormant compromises reactivate for free.

To further enhance your cloud security and implement Zero Trust, contact me on LinkedIn Profile or [email protected].

Indicators of Compromise (IOCs)

TypeIndicatorNotes
Compromised actionactions-cool/issues-helper (all release tags)Malicious content from May 18, 2026 still referenced at re-enablement
Compromised actionactions-cool/maintain-one-comment (all release tags)Same exposure window
Malicious commita0c53dd42fc842d2f9276c5a1d4f9a26abe8713dWhat @v2.2.1 resolved to; obfuscated payload in index.js
Exfil domaint.m-kosche[.]comLinks to Mini Shai-Hulud / @antv npm cluster
Runner log markeroven-sh/setup-bun + bun run $GITHUB_ACTION_PATH/index.jsPayload execution inside either action
Run anomalySetup failures → sudden multi-minute successes after Sept 16Detection heuristic

Frequently Asked Questions (FAQ)

Which GitHub Actions were re-enabled with malicious code?

actions-cool/issues-helper and actions-cool/maintain-one-comment. Compromised May 18, 2026 in the Mini Shai-Hulud campaign and disabled May 19, they became downloadable again on September 16 with malicious tags intact, and were disabled a second time on September 25.

Am I affected if my workflow uses these actions?

Only tag-based references (e.g. @v2.2.1) are affected. Workflows pinned to the full commit SHA of a version predating May 18, 2026 are not impacted by the tag compromise or the re-enablement.

How do I know if my repo executed the payload?

Check workflow run history for runs that started succeeding after prolonged Set up job failures, durations jumping from seconds to minutes, or runner logs showing oven-sh/setup-bun and bun run $GITHUB_ACTION_PATH/index.js. Any tag-reference run on or after September 16 should be treated as exposed.

What should I do first?

Replace tag references with a verified pre-May-18 full commit SHA or remove the actions, rotate every secret the workflow could access, audit repo history for unexpected commits since September 16, and pin all third-party actions to SHAs going forward.

Why did this happen without a new attack?

Disabling a repository blocks downloads but does not clean malicious tags. Re-enabling restored the only removed barrier, so the months-old compromise reactivated across the dependency graph (~15,000 repos for issues-helper alone) with no new attacker action.


William OGOU

William OGOU

Need help implementing Zero Trust strategy or securing your cloud infrastructure? I help organizations build resilient, compliance-ready security architectures.