Back to Intelligence

Mini Shai-Hulud Resurgence: Compromised actions-cool GitHub Actions Re-Activated — Detection and Remediation Guide

SA
Security Arsenal Team
September 25, 2026
12 min read

The Mini Shai-Hulud supply-chain campaign is not over. Two GitHub Actions maintained under the actions-cool organization — actions-cool/issues-helper and actions-cool/maintain-one-comment — were disabled for a second time after their repositories unexpectedly became accessible again last week and resumed executing the Mini Shai-Hulud malware, months after their original compromise during the May 2026 campaign wave. Anyone visiting the repositories now sees GitHub's access-disabled notice, but the damage window — however short — is real: any workflow that referenced these actions by mutable tag (e.g., @v3, @main) during the re-exposure window potentially executed attacker-controlled code inside a CI runner with access to GITHUB_TOKEN, cloud credentials, and npm publishing tokens.

This is the nightmare scenario for supply-chain defenders: a threat you believed was contained silently re-activating. If your organization consumes community GitHub Actions — and statistically, it does — treat this as an active incident until proven otherwise.

What Happened

The timeline matters for scoping your exposure:

  • May 2026: The actions-cool repositories were compromised as part of the Mini Shai-Hulud campaign — a descendant of the original September 2025 Shai-Hulud npm worm that weaponized CI/CD trust relationships to harvest credentials and self-propagate.
  • Interim: GitHub disabled both repositories. Most defenders reasonably considered the risk closed.
  • Last week (September 2026): Both repositories became accessible again. Workflows referencing them began resolving and executing the poisoned action code — meaning the malware ran again in consumer pipelines.
  • Now: GitHub has disabled the repositories a second time. They currently return an access-disabled message.

Affected actions:

  • actions-cool/issues-helper
  • actions-cool/maintain-one-comment

issues-helper in particular is a popular utility for automating issue/PR labeling and commenting — it appears in a large number of public and private repositories, typically referenced by version tag rather than commit SHA, which is precisely the consumption pattern this campaign exploits.

Technical Analysis: How Mini Shai-Hulud Operates in a CI Runner

Mini Shai-Hulud inherits the core tradecraft of the Shai-Hulud worm family, optimized for CI/CD environments. From a defender's perspective, the attack chain inside your runner looks like this:

  1. Action resolution: A workflow step referencing actions-cool/issues-helper@v3 (or any mutable ref) resolves to the compromised repository. The runner downloads and executes the poisoned JavaScript via Node.js under the Runner.Worker process tree.
  2. Environment harvesting: The payload enumerates the runner environment — dumping environment variables (printenv/env via Node's process.env), reading ${GITHUB_ENV}, and extracting the ephemeral GITHUB_TOKEN, plus any cloud credentials present (AWS, GCP, Azure), npm tokens (NPM_TOKEN, ~/.npmrc), and SSH keys.
  3. Secret scanning at scale: Consistent with the Shai-Hulud family, the malware stages or invokes a TruffleHog-style secret scanner against the checked-out repository and filesystem to find long-lived credentials in source, config files, and git history.
  4. Exfiltration: Stolen material is exfiltrated over HTTPS to attacker-controlled endpoints — the original Shai-Hulud campaign famously used webhook.site collectors and abused the GitHub API itself (creating repositories named Shai-Hulud in victim accounts to stage stolen data). Mini Shai-Hulud variants have continued both patterns.
  5. Propagation: Where an npm token with publish rights is recovered, the worm pushes trojanized versions of the victim's packages with malicious postinstall lifecycle scripts — converting every victim into a new distribution point. Where a GITHUB_TOKEN has write scope, it can inject workflows or modify workflow files (.github/workflows/*.yml) to establish persistence in the repository itself.

Exploitation requirements: None beyond consuming the action. No user interaction, no misconfiguration — a routine scheduled or PR-triggered workflow run is sufficient. The re-exposure window means even organizations that "survived" May may have been hit last week if a workflow ran while the repos were back online.

Exploitation status: Confirmed active. This is not theoretical — GitHub's second disable action confirms malicious code was reachable and executing. No CVE is associated with this campaign; it is a supply-chain compromise of trusted action code, not a software vulnerability in the traditional sense. Accordingly, no CISA KEV entry applies — scoping and response are entirely on you.

Scoping Your Exposure: The First 60 Minutes

Before touching detection engineering, answer three questions:

  1. Do we use these actions? Search every repository's workflow files for actions-cool/issues-helper and actions-cool/maintain-one-comment. Include archived repos and non-default branches.
  2. Did any workflow run during the re-exposure window? Cross-reference workflow run history (gh run list) against last week's dates. A workflow referencing the action that ran while the repo was accessible = assume compromise of that run's secrets.
  3. What secrets were in scope? Enumerate repository secrets, environment secrets, org-level secrets, OIDC cloud roles assumable from the workflow, and any npm tokens. Every one of these is a rotation candidate.

If the answer to (2) is yes, you are in incident response mode: rotate credentials, review audit logs for anomalous use of the GITHUB_TOKEN (unexpected repo creation, workflow file modification, package publishes), and hunt for downstream propagation.

Detection & Response

The detections below target Mini Shai-Hulud's observable behaviors in CI runners and developer endpoints — credential enumeration, secret-scanner staging, exfiltration to collector endpoints, and workflow-file tampering. Tune runner hostnames and paths to your environment.

YAML
---
title: CI Runner Secret Enumeration and Exfiltration via Node.js
description: Detects Node.js or GitHub Actions runner processes spawning shells or network tools consistent with Mini Shai-Hulud payload execution inside CI runners.
references:
  - https://thehackernews.com/2026/09/compromised-github-actions-came-back.html
  - https://attack.mitre.org/techniques/T1552/
  - https://attack.mitre.org/techniques/T1195/
author: Security Arsenal
date: 2026/09/15
id: 3f8a2c71-6b4d-4e9a-b1c7-9d2e5f0a8b3c
status: experimental
tags:
  - attack.collection
  - attack.exfiltration
  - attack.t1552.001
  - attack.t1195.002
logsource:
  category: process_creation
  product: linux
detection:
  selection_parent:
    ParentImage|endswith:
      - '/node'
      - '/Runner.Worker'
      - '/npm'
  selection_child:
    Image|endswith:
      - '/sh'
      - '/bash'
      - '/curl'
      - '/wget'
  selection_cmd:
    CommandLine|contains:
      - 'printenv'
      - 'webhook.site'
      - 'id_token'
      - '/proc/'
      - '.npmrc'
  condition: selection_parent and (selection_child or selection_cmd)
falsepositives:
  - Legitimate build tooling spawning shell commands; tune against known-good runner images
level: high
---
title: TruffleHog-Style Secret Scanner Execution from Non-Standard Path
description: Detects execution of secret-scanning binaries (trufflehog or renamed copies) from temporary or runner working directories, a hallmark of Shai-Hulud family credential harvesting.
references:
  - https://thehackernews.com/2026/09/compromised-github-actions-came-back.html
  - https://attack.mitre.org/techniques/T1552/
author: Security Arsenal
date: 2026/09/15
id: 7c1d4e92-3a5f-4b8d-9e2c-1f6a0b4d8e7a
status: experimental
tags:
  - attack.credential_access
  - attack.t1552
logsource:
  category: process_creation
  product: linux
detection:
  selection_img:
    Image|contains:
      - '/tmp/'
      - '/home/runner/work/'
      - '/dev/shm/'
  selection_name:
    Image|contains:
      - 'trufflehog'
  selection_args:
    CommandLine|contains:
      - 'filesystem'
      - '--no-verification'
      - 'git file://'
  condition: selection_img and (selection_name or selection_args)
falsepositives:
  - Sanctioned secret-scanning jobs in CI pipelines; allowlist known scanning workflow paths
level: high
---
title: GitHub Workflow File Modification Outside Expected Build Process
description: Detects writes to .github/workflows YAML files by processes other than git or developer tooling, indicating potential workflow injection for CI persistence as seen in Shai-Hulud propagation.
references:
  - https://thehackernews.com/2026/09/compromised-github-actions-came-back.html
  - https://attack.mitre.org/techniques/T1554/
author: Security Arsenal
date: 2026/09/15
id: 9e2b6d14-8c7a-4f3b-a5d1-6c9e0f2b4a8d
status: experimental
tags:
  - attack.persistence
  - attack.defense_evasion
logsource:
  category: file_event
  product: linux
detection:
  selection_path:
    TargetFilename|contains:
      - '.github/workflows/'
  selection_ext:
    TargetFilename|endswith:
      - '.yml'
      - '.yaml'
  filter_legit:
    Image|endswith:
      - '/git'
      - '/code'
      - '/vim'
      - '/nano'
  condition: selection_path and selection_ext and not filter_legit
falsepositives:
  - Repository scaffolding or automation tools that legitimately manage workflow files
level: medium

KQL — Microsoft Sentinel / Defender

This query hunts the process trees most indicative of Mini Shai-Hulud execution: Node.js or runner processes invoking shells/network utilities with credential-harvesting or exfiltration command lines. It assumes Defender for Endpoint coverage on self-hosted runners, or Syslog/CEF ingestion of runner telemetry into Sentinel.

KQL — Microsoft Sentinel / Defender
let Lookback = 14d;
let SuspiciousCmd = dynamic(["webhook.site", "printenv", "/proc/self/environ", ".npmrc", "trufflehog", "id_token", "npm publish", "gh api"]);
DeviceProcessEvents
| where Timestamp > ago(Lookback)
| where InitiatingProcessFileName in~ ("node", "Runner.Worker", "npm", "Runner.Listener")
   or InitiatingProcessCommandLine has_any ("actions-runner", "Runner.Worker")
| where FileName in~ ("sh", "bash", "curl", "wget", "env", "python", "python3")
   or ProcessCommandLine has_any (SuspiciousCmd)
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine,
          FileName, ProcessCommandLine, AccountName, ReportId
| order by Timestamp desc;
// Companion: network exfiltration from runner processes
DeviceNetworkEvents
| where Timestamp > ago(Lookback)
| where InitiatingProcessFileName in~ ("node", "curl", "wget", "Runner.Worker")
| where RemoteUrl has_any ("webhook.site", "pastebin", "ngrok")
   or (RemoteUrl contains "api.github.com" and InitiatingProcessFileName =~ "curl")
| project Timestamp, DeviceName, InitiatingProcessFileName, RemoteUrl, RemoteIP, RemotePort
| order by Timestamp desc;

Velociraptor VQL

For incident scoping on self-hosted runners, this artifact pulls suspicious process executions and inventories workflow files for recent tampering.

VQL — Velociraptor
-- Mini Shai-Hulud runner triage: suspicious processes and workflow file artifacts
SELECT Pid, Ppid, Name, Exe, CommandLine, Username, CreateTime
FROM pslist()
WHERE CommandLine =~ '(webhook\.site|printenv|trufflehog|\.npmrc|/proc/self/environ|npm publish)'
   OR (Name =~ '(?i)node|Runner\.Worker' AND CommandLine =~ '(?i)curl|wget|bash -c')

-- Inventory workflow files modified in the last 14 days
SELECT FullPath, Size, Mtime, Ctime
FROM glob(globs='*/.github/workflows/*.y*ml')
WHERE Mtime > now() - 1209600
ORDER BY Mtime DESC

Exposure Audit and Hardening Script

Run this against your GitHub organization (requires the gh CLI authenticated with org read scope). It identifies consumption of the compromised actions, flags unpinned community actions, and inventories recent workflow runs during the re-exposure window.

Bash / Shell
#!/bin/bash
# Mini Shai-Hulud exposure audit — Security Arsenal
# Usage: ./shaihulud-audit.sh <org-name>
set -euo pipefail
ORG="${1:?Usage: $0 <github-org>}"
REPORT="shaihulud-audit-$(date +%Y%m%d).txt"

echo "=== Mini Shai-Hulud Exposure Audit: ${ORG} ===" | tee "$REPORT"

# 1. Find all references to the compromised actions across the org
echo -e "\n[1] Repositories referencing actions-cool actions:" | tee -a "$REPORT"
gh search code "org:${ORG} actions-cool/issues-helper" --json repository,path \
  --jq '.[] | "\(.repository.nameWithOwner) -> \(.path)"' | tee -a "$REPORT" || true
gh search code "org:${ORG} actions-cool/maintain-one-comment" --json repository,path \
  --jq '.[] | "\(.repository.nameWithOwner) -> \(.path)"' | tee -a "$REPORT" || true

# 2. Flag community actions pinned by mutable tag instead of commit SHA (risky pattern)
echo -e "\n[2] Workflows using mutable (non-SHA) action refs:" | tee -a "$REPORT"
gh api "orgs/${ORG}/repos" --paginate --jq '.[].full_name' | while read -r repo; do
  gh api "repos/${repo}/git/trees/HEAD?recursive=1" \
    --jq '.tree[] | select(.path | test("^\\.github/workflows/.*\\.ya?ml$")) | .path' 2>/dev/null \
  | while read -r wf; do
      content=$(gh api "repos/${repo}/contents/${wf}" --jq '.content' 2>/dev/null | base64 -d || true)
      echo "$content" | grep -E 'uses:\s+[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+@(v[0-9]|main|master)' \
        | sed "s|^|${repo}/${wf}: |" | tee -a "$REPORT" || true
    done
done

# 3. Check for Shai-Hulud IOC repositories created in the org (self-propagation artifact)
echo -e "\n[3] Suspicious 'Shai-Hulud' named repos (propagation artifact):" | tee -a "$REPORT"
gh api "orgs/${ORG}/repos" --paginate \
  --jq '.[] | select(.name | test("(?i)shai.hulud")) | .full_name' | tee -a "$REPORT" || true

# 4. List workflow runs from the re-exposure window (adjust dates to your intel)
echo -e "\n[4] Workflow runs during re-exposure window (2026-09-01 to present):" | tee -a "$REPORT"
gh api "orgs/${ORG}/repos" --paginate --jq '.[].full_name' | while read -r repo; do
  gh run list --repo "$repo" --created ">=2026-09-01" --limit 50 \
    --json databaseId,workflowName,createdAt,conclusion \
    --jq '.[] | "'"$repo"' | \(.workflowName) | \(.createdAt) | \(.conclusion)"' 2>/dev/null | tee -a "$REPORT" || true
done

echo -e "\nAudit complete. Review ${REPORT}. Any hit in section [1] combined with runs in [4] = IR mode."

Remediation

There is no patch to apply — this is a compromise of trusted third-party code, so remediation is architectural and credential-focused. Execute in this order:

  1. Remove the compromised actions immediately. Delete or replace all references to actions-cool/issues-helper and actions-cool/maintain-one-comment in every workflow, on every branch, in every repository — including forks and archived repos. Do not wait for a "fixed" version; the maintainer's release pipeline must be considered untrusted until independently verified.

  2. Rotate every secret reachable from affected workflows. This includes repository and environment secrets, org-level secrets, NPM_TOKEN and any token in .npmrc, cloud credentials (AWS keys, GCP service account keys, Azure secrets), SSH deploy keys, and Personal Access Tokens used by automation. Assume any secret present in a runner that executed these actions during either the May compromise or last week's re-exposure is in attacker hands. Rotation — not review — is the correct default.

  3. Review audit trails for post-compromise activity. In GitHub: audit log entries for unexpected repository creation (particularly repos named Shai-Hulud), workflow file modifications, new deploy keys, and package publishes. In npm: check for unexpected package version publishes from maintainer accounts. In cloud providers: CloudTrail/audit logs for access from unfamiliar IPs using CI-scoped credentials.

  4. Pin every third-party action to a full-length commit SHA. Mutable tags (@v3, @main) are the delivery mechanism for this class of attack. A SHA pin makes yesterday's compromise unable to reach today's pipeline. Use Dependabot or Renovate to manage SHA updates with review.

  5. Adopt a GitHub Actions allowlist policy. GitHub Enterprise supports restricting workflows to verified creators or an explicit allowlist (Settings > Actions > Allow select actions). If you cannot allowlist today, at minimum block actions from outside your org plus a vetted list.

  6. Minimize GITHUB_TOKEN blast radius. Set default token permissions to read-only at the org level and grant permissions: explicitly per job. This breaks Mini Shai-Hulud's repository-write propagation path even if a payload executes.

  7. Migrate CI-to-cloud authentication to OIDC. Replace long-lived cloud secrets in GitHub with OIDC federation (short-lived, audience-scoped tokens). A stolen OIDC token expires in minutes; a stolen AWS key is a breach until you notice.

  8. Lock down npm publishing. Require granular, publish-scoped automation tokens (never legacy tokens), enforce 2FA for publishing, and enable npm's trusted publishing / provenance where available. Audit package.json files for unexpected preinstall/postinstall scripts — the worm's propagation vehicle.

  9. Monitor for recurrence — because it recurs. This campaign demonstrates that disabled repositories can come back. Alert on any workflow resolution of actions-cool/* and on new references to actions from maintainers with prior compromise history.

The Bigger Lesson

Mini Shai-Hulud's resurrection is a case study in why supply-chain incident response cannot end at "the vendor disabled the repo." Your trust dependency was the vulnerable component, and trust dependencies re-activate. The organizations that weathered last week cleanly share three traits: SHA-pinned actions, OIDC-based cloud auth, and least-privilege GITHUB_TOKEN defaults. None of those require a new tool — they require deciding that your CI pipeline is production infrastructure and defending it accordingly.

If your audit reveals workflow runs against these actions during the re-exposure window, treat it as a confirmed credential compromise and engage your IR process. Security Arsenal's incident response team has handled multiple Shai-Hulud-family engagements since 2025 and can assist with scoping, rotation, and downstream propagation analysis.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.