Full Report
The compromise originated from a GitHub Actions script injection vulnerability in a workflow that improperly handled untrusted input from pull request comments. An attacker exploited this flaw to execute arbitrary commands within the CI pipeline, gaining access to the reposito...
Analysis Summary
# Incident Report: Elementary Data Supply Chain Compromise
## Executive Summary
Elementary Data suffered a supply chain compromise resulting from a GitHub Actions script injection vulnerability. An attacker exploited improper handling of pull request comments to hijack the CI/CD pipeline, publishing malicious versions of the `elementary-data` package to PyPI and GHCR. The malicious software was designed to harvest cloud credentials, SSH keys, and developer tokens from infected environments.
## Incident Details
- **Discovery Date:** April 2026 (Reported April 23, 2026)
- **Incident Date:** April 2026
- **Affected Organization:** Elementary Data
- **Sector:** Software Development / Data Observability
- **Geography:** Global
## Timeline of Events
### Initial Access
- **Date/Time:** April 2026
- **Vector:** GitHub Actions Script Injection (1-day vulnerability)
- **Details:** The attacker exploited a workflow that improperly handled untrusted input from pull request comments, allowing for arbitrary command execution within the CI runner.
### Lateral Movement
- The attacker used the script injection to gain access to the repository's `GITHUB_TOKEN`.
- Leveraging this token, the attacker forged a signed commit and triggered the legitimate release pipeline manually.
### Data Exfiltration/Impact
- A malicious version (v0.23.3) was published to PyPI and GHCR (including the `:latest` tag).
- The package included a `.pth` file (`elementary.pth`) that automatically executed a three-stage credential harvester upon Python startup.
- Collected data included AWS/GCP/Azure credentials, SSH keys, Kubernetes secrets, and crypto wallets.
### Detection & Response
- **How it was discovered:** Identified via security research and monitoring of PyPI/GHCR releases.
- **Response actions taken:** Community and vendor notification; removal of malicious versions from PyPI and GHCR.
## Attack Methodology
- **Initial Access:** Misconfigured GitHub Action abuse (injection via PR comments).
- **Persistence:** Implementation of a `.pth` file in the Python environment, ensuring execution every time the interpreter starts.
- **Privilege Escalation:** Exploiting CI/CD runner permissions to obtain `GITHUB_TOKEN`.
- **Defense Evasion:** Use of layered obfuscation (Base64 + XOR/MD5) to bypass static analysis and signature-based detection.
- **Credential Access:** Harvesting local configuration files for cloud providers (AWS, Azure, GCP) and developer tools.
- **Discovery:** Automated scanning of local files and live cloud APIs for secrets.
- **Exfiltration:** Data compressed and sent via HTTP POST to a remote C2 domain.
- **Impact:** Supply chain compromise affecting downstream users of the PyPI package and container images.
## Impact Assessment
- **Financial:** Potential loss of assets via compromised crypto wallets; unauthorized cloud resource usage.
- **Data Breach:** High-severity theft of cloud management credentials, SSH keys, and Kubernetes secrets.
- **Operational:** Integrity compromise of the CI/CD pipeline and distributed software images.
- **Reputational:** Damage to trust in the Elementary Data open-source project and distribution channels.
## Indicators of Compromise
- **Network indicators:**
- C2 Exfiltration Domain: `https[:]//stepsecurity[.]io/blog/elementary-data-compromised...` (Referenced for IoC details)
- **File indicators:**
- `elementary.pth` (Malicious Python path file)
- `elementary-data` v0.23.3 (Malicious PyPI version)
- **Behavioral indicators:**
- Unexpected outbound HTTP POST traffic from development or CI environments.
- Verified commits in GitHub created without a corresponding Pull Request.
## Response Actions
- **Containment:** Removal of the compromised version (v0.23.3) from PyPI and GHCR.
- **Eradication:** Revocation of the compromised `GITHUB_TOKEN` and hardening of the GitHub Action workflow.
- **Recovery:** Release of a clean version and advisory for users to rotate all secrets stored in environments where the malicious version was installed.
## Lessons Learned
- **Key takeaways:** Use of untrusted input (like PR comments) in GitHub Action "run" steps is extremely high risk.
- **Gaps:** The CI/CD pipeline allowed signed commits and releases without mandatory manual approvals or branch protection overrides.
## Recommendations
- **Workflow Hardening:** Use `github.event.comment.body` only in environments that are properly sanitized or using action-level protections.
- **Least Privilege:** Limit the scope of `GITHUB_TOKEN` permissions to "read-only" where possible.
- **Pinning:** Downstream users should use hashed pins for container images and specific versions for PyPI packages to avoid automatic updates to compromised `:latest` tags.
- **Audit:** Implement OIDC for publishing to PyPI to remove the need for long-lived secrets in CI/CD.