6188
Open Source

Elementary Data PyPI Compromise: Q&A on the GitHub Actions Attack

Posted by u/296626 Stack · 2026-05-03 10:18:37

In a recent supply chain attack, the open-source Python CLI tool elementary-data was compromised when an attacker exploited a vulnerability in a GitHub Actions workflow. The incident highlights how even well-maintained projects can be targeted, with the malicious package reaching PyPI within minutes. Below, we answer key questions about the breach, its impact, and what affected users should do.

What exactly happened in the Elementary Data compromise?

On April 24, at 22:10 UTC, an attacker posted a crafted comment on a pull request within Elementary Data's GitHub repository. The comment was not just text—it contained shell commands. Because the project's GitHub Actions workflow was configured to directly execute text from PR comments as part of a shell command, the runner treated the malicious input as code. This gave the attacker access to sensitive environment variables stored as secrets, including the PyPI publish token and the GITHUB_TOKEN. With these credentials, the attacker created new branches, opened staged pull requests, and triggered the official release workflow. By 22:20 UTC, version 0.23.3 of elementary-data was live on PyPI, and a poisoned Docker image followed four minutes later. The entire attack window was remarkably short, demonstrating how quickly a simple misconfiguration can lead to a full compromise.

Elementary Data PyPI Compromise: Q&A on the GitHub Actions Attack
Source: itsfoss.com

How did the attacker exploit the GitHub Actions workflow?

The root cause was an insecure design in one of Elementary's GitHub Actions workflows. A step in the workflow used bash to evaluate user input from pull request comments directly, without sanitization. Specifically, the workflow passed the comment text into a shell command like echo "${{ github.event.comment.body }}"—but with a twist that allowed arbitrary command execution. When the attacker submitted a PR comment containing shell metacharacters (e.g., backticks or $(...)), the runner expanded them. This technique, known as script injection, allowed the attacker to execute arbitrary commands in the runner's environment. Once the malicious code ran, it exfiltrated the PYPI_TOKEN and GITHUB_TOKEN secrets. With those tokens, the attacker could authenticate as the project's maintainer and push a new release to PyPI. The vulnerability existed because the workflow had pull_request_target event trigger, which grants elevated permissions, combined with unsafe input handling.

Which users were affected by this attack?

Only a narrow set of users are at risk. The malicious version 0.23.3 of elementary-data was published to PyPI and hosted on Docker Hub as a compromised image. Anyone who installed or updated to that specific version during the short window (approximately 22:20 UTC on April 24 to April 25 when it was removed) is potentially affected. Users of Elementary Cloud, the Elementary dbt package, and all other CLI versions (0.23.2 and earlier, or 0.23.4 and later) are safe. However, if you ran 0.23.3, the exposure is serious. The malware could access any credentials, environment variables, or files that the runtime environment could reach—including CI/CD secrets, cloud provider tokens, and database credentials. Check your installed version immediately.

How can I check if my system was compromised?

Start by verifying the installed version of elementary-data. Run the command:

pip show elementary-data | grep Version

If it returns 0.23.3, your system is affected. Next, look for a marker file left behind by the malware. The file's path depends on your operating system:

Elementary Data PyPI Compromise: Q&A on the GitHub Actions Attack
Source: itsfoss.com
  • Linux/macOS: /tmp/.trinny-security-update
  • Windows: %TEMP%\.trinny-security-update

If this marker file exists, it indicates that the malicious code executed on that machine. Note that the absence of the file does not guarantee safety—the payload may have been deleted or the attack may have been partial. For thoroughness, also review any unusual outbound network connections or unauthorized changes to credentials during the attack window.

What steps should affected users take to clean up?

If you find you have version 0.23.3 installed, follow these steps immediately:

  1. Remove the compromised package: Run pip uninstall elementary-data and then install the clean version pip install elementary-data==0.23.4. Update your requirements.txt or lockfiles accordingly.
  2. Rotate all credentials: Any environment variable, API key, or secret that was accessible to the compromised environment should be considered exposed. Rotate them and revoke old tokens.
  3. Check for the marker file as described above. If found, treat the machine as fully compromised—engage your security team for forensic analysis.
  4. Monitor logs: Look for suspicious activity using any credentials that were present in the environment. Pay special attention to actions taken between the attack time (April 24, 22:10 UTC) and the time you removed the malware.

If you use Docker, also remove any pulled image tagged elementary-data:0.23.3 and pull the latest clean version.

What has Elementary Data done to prevent future attacks?

Upon discovering the breach on April 25, Elementary Data acted quickly. They removed the malicious version from PyPI, GitHub Releases, and Docker Hub. The compromised workflow was decommissioned entirely. They also performed an audit of all remaining GitHub Actions workflows to identify similar injection vulnerabilities. All exposed secrets were regenerated, and the project has since migrated to OIDC-based authentication, which eliminates the need for long-lived tokens that can be stolen. Additionally, they are working with an Israeli cybersecurity firm to conduct a full investigation and implement stronger guardrails against supply chain attacks. This incident serves as a reminder for all open-source maintainers to sanitize user input, use least-privilege principles in CI/CD, and adopt modern authentication like OIDC.