Fbhchile

How to Detect and Recover from a GitHub Actions Compromise Targeting PyPI Packages

Learn to identify if you were affected by the elementary-data PyPI compromise, remove malicious code, and secure GitHub Actions against similar attacks.

Fbhchile · 2026-05-01 23:38:30 · Open Source

Introduction

Open-source supply chain attacks are becoming increasingly common, with attackers exploiting misconfigured CI/CD pipelines to push malicious code to package repositories. A recent incident involving Elementary Data's Python CLI (elementary-data) demonstrated how a single vulnerable GitHub Actions workflow allowed an attacker to publish a compromised version (0.23.3) to PyPI. If you installed that version, your environment may be at risk. This guide walks you through detecting the infection, cleaning it up, and hardening your own workflows to prevent similar attacks.

How to Detect and Recover from a GitHub Actions Compromise Targeting PyPI Packages
Source: itsfoss.com

What You Need

  • Access to the machine(s) where elementary-data is installed
  • Command-line terminal (Linux/macOS/Windows)
  • pip package manager
  • Administrative privileges to uninstall packages and rotate credentials
  • List of all credentials (API tokens, secrets) your environment has access to

Step 1: Check Your Installed Version

First, determine whether you have the affected version (0.23.3) installed. Run this command in your terminal:

pip show elementary-data | grep Version

If the output shows Version: 0.23.3, proceed immediately to the next steps. If you see a different version (or the package is not installed), you are not affected by this particular attack — but you should still review your GitHub Actions security (see Tips section).

Step 2: Remove the Malicious Package

If version 0.23.3 is present, uninstall it with pip:

pip uninstall elementary-data

Confirm the removal when prompted. This deletes the compromised package files but does not revert any system changes the malware may have made.

Step 3: Install the Clean Version

After uninstalling, install the patched version published by Elementary:

pip install elementary-data==0.23.4

This ensures you are using a safe release. Also update your requirements.txt, Pipfile.lock, or any other dependency manifests to pin elementary-data==0.23.4.

Step 4: Detect the Malware’s Marker File

The malicious payload left a marker file on the filesystem. Check for its presence to confirm whether the malware actually executed on your machine:

  • Linux/macOS: Look for /tmp/.trinny-security-update
  • Windows: Look for %TEMP%\.trinny-security-update

Run the appropriate command in your terminal:

# Linux/macOS
ls -la /tmp/.trinny-security-update

# Windows (PowerShell)
Test-Path $env:TEMP\.trinny-security-update

If the file exists, the malware executed on that machine. If it does not exist, the attack may still have occurred but did not run the payload — however, you should still rotate credentials as a precaution.

Step 5: Rotate All Credentials in the Affected Environment

If the marker file is present (or if you are uncertain), assume all secrets accessible from that environment are compromised. Immediately:

  • Generate new API keys, tokens, and passwords for every service the environment interacts with.
  • Revoke the old credentials via each service’s administration interface.
  • Notify your security team and monitor for suspicious activity on recently rotated credentials.

Pay special attention to credentials used in CI/CD pipelines, cloud provider roles, and any database or storage endpoints.

How to Detect and Recover from a GitHub Actions Compromise Targeting PyPI Packages
Source: itsfoss.com

Step 6: Harden Your Own GitHub Actions Workflows

To prevent similar attacks on your projects, review your GitHub Actions configurations. The Elementary compromise originated from a workflow that passed user‑provided text from a pull request comment directly into a shell command. Always avoid using untrusted input in script steps. Replace with safer alternatives:

  • Use OIDC tokens instead of long‑lived secrets where possible.
  • Restrict the ability to run workflows on pull requests from forks.
  • Validate any external input before using it in shell commands.
  • Audit all your workflows for command injection vulnerabilities (e.g., using ${{ github.event.comment.body }} in a run: step).

Elementary decommissioned the vulnerable workflow, regenerated secrets, and moved to OIDC authentication. Follow their lead: enable OpenID Connect for your cloud providers and use secrets.GITHUB_TOKEN with minimal permissions.

Tips for Long‑Term Security

  • Monitor your repositories: Set up alerts for unusual PR comments or workflow triggers. GitHub offers audit log streaming for enterprise accounts.
  • Pin action versions: Always reference GitHub Actions by commit SHA, not by tag, to avoid accidental inclusion of compromised updates.
  • Use separate deployment workflows: Keep release workflows distinct from CI workflows and require manual approval for publishing packages.
  • Regularly rotate secrets: Even without a breach, rotate API tokens and deploy keys every 90 days.
  • Test incident response: Run tabletop exercises simulating a supply chain attack to ensure your team can detect and react quickly.

By following these steps, you can recover from the elementary-data incident and strengthen your defenses against future GitHub Actions–based attacks. Remember that security is a continuous process — stay informed about new attack vectors and update your practices accordingly.

Recommended