● LIVE   Breaking News & Analysis
Usahobs
2026-05-01
Open Source

How to Detect and Recover from a Compromised Python Package Attack (GitHub Actions Hijack)

Step-by-step guide to detect and recover from the elementary-data 0.23.3 compromise: check version, uninstall, install patched version, verify marker file, rotate credentials, plus CI/CD hardening tips.

Introduction

Open source projects are increasingly becoming targets for malicious actors, and the attack surface is vast. In a recent incident, Elementary Data's open source Python CLI was compromised when an attacker exploited a vulnerability in a GitHub Actions workflow. By injecting code through a pull request comment, the attacker gained access to secrets, published a malicious version (0.23.3) to PyPI, and pushed a harmful Docker image. This guide walks you through the steps to check if you're affected, remove the malicious package, and secure your environment. Even if you weren't directly impacted, the tips at the end will help you fortify your own workflows.

How to Detect and Recover from a Compromised Python Package Attack (GitHub Actions Hijack)
Source: itsfoss.com

What You Need

  • A terminal or command prompt with Python and pip installed
  • Access to your project's requirements.txt or lockfiles
  • Your GitHub repository (if you manage CI/CD pipelines)
  • List of credentials your environment uses (API keys, tokens, etc.)

Step-by-Step Guide

Step 1: Check Your Installed Version of elementary-data

Open your terminal (Linux/macOS) or command prompt (Windows). Run the following command:

pip show elementary-data | grep Version

If the output shows Version: 0.23.3, your system contains the compromised package. If it shows any other version (e.g., 0.23.2 or 0.23.4), you are safe from this specific attack. However, even if you see 0.23.3, proceed immediately to the next steps.

Step 2: Remove the Malicious Version

If you found version 0.23.3 installed, uninstall it completely:

pip uninstall elementary-data

Confirm the uninstallation when prompted. This removes the compromised package files but does not automatically revert any damage the malware may have done (like stolen credentials).

Step 3: Install the Clean Version

Now install the patched, safe version of the package:

pip install elementary-data==0.23.4

This version (0.23.4) is the officially released fix that does not contain the malicious code. After installation, verify that it shows the correct version:

pip show elementary-data | grep Version

Expected output: Version: 0.23.4.

Step 4: Update Your Requirements and Lockfiles

If you manage dependencies with requirements.txt, Pipfile, pyproject.toml, or a lockfile (like requirements.lock), edit those files to replace elementary-data==0.23.3 with elementary-data==0.23.4. For example:

# requirements.txt (old)
elementary-data==0.23.3

# requirements.txt (new)
elementary-data==0.23.4

If you use a package manager like Poetry or PDM, run the appropriate update command (e.g., poetry add elementary-data@^0.23.4). Commit these changes to your repository to prevent reinstallation of the malicious version.

Step 5: Check for the Malware Marker File

The attacker's payload created a marker file if it executed successfully. Check for its presence:

  • Linux/macOS: Look for /tmp/.trinny-security-update. Run ls -la /tmp/.trinny-security-update.
  • Windows: Look for %TEMP%\.trinny-security-update. Open File Explorer and navigate to %TEMP%, then check for a file named .trinny-security-update (note the leading dot).

If the file exists, the malicious code has run on that machine. Do not delete it yet – treat it as evidence and continue to the next step.

Step 6: Rotate All Credentials if Marker Found

If you found the marker file, assume every secret accessible from that environment is compromised. Immediately:

  • Rotate all API keys, tokens, passwords, and certificates that were used or stored on that machine.
  • Revoke the PyPI publish token (if you are a maintainer).
  • Regenerate GITHUB_TOKEN or any other CI/CD secrets.
  • Notify your security team and provide them with the marker file location and any logs from the time of the attack.

If no marker file exists, the malicious package may not have executed on that particular machine – but it's still prudent to rotate any credentials that the package could have accessed (e.g., environment variables).

How to Detect and Recover from a Compromised Python Package Attack (GitHub Actions Hijack)
Source: itsfoss.com

Step 7: Remove Any Pulled Malicious Docker Images

The attack also pushed a malicious Docker image. If you pulled any Elementary Docker images during the attack window (April 24–25), check the image tag. The compromised image was likely tagged with 0.23.3 or similar. Run:

docker images | grep elementary

If you see an image with version 0.23.3, remove it:

docker rmi <image-id>

Then pull the latest safe image:

docker pull elementary-data:latest

Or use the specific patched tag after verifying it's available.

Tips to Prevent Future Attacks

This attack exploited a GitHub Actions workflow that directly executed shell commands from pull request comments. Here are actionable ways to harden your CI/CD pipelines:

  • Avoid inline shell execution from untrusted input. Never pass PR comment text directly into run: or ${{ }} without sanitization. Use step-level conditionals or explicit environment variables.
  • Switch to OIDC-based authentication. OpenID Connect (OIDC) eliminates the need for long-lived secrets. Elementary Data has already moved to OIDC – you should too.
  • Audit all workflows for the same vulnerability. Review any place where a comment, issue body, or PR description is used in a shell command. Restrict the permissions of GITHUB_TOKEN to the minimum required.
  • Use job-level permissions with least privilege. Set permissions: in your workflow to read-only by default, and grant write access only to specific jobs that need it.
  • Pin actions to full-length commit SHAs. Instead of using tags like @v1, use the commit SHA to prevent supply chain attacks on third-party actions.
  • Monitor dependency versions automatically. Tools like Dependabot or Renovate can alert you when a package version is compromised or updated.
  • Have an incident response plan. Know who to contact, how to revoke secrets quickly, and how to notify users if a malicious version slips through.

By following these steps, you can mitigate the damage from this specific attack and strengthen your defenses against future supply chain threats. Stay vigilant and keep your packages and pipelines secure.