Security News

Cybersecurity news aggregator

CRITICAL Attacks Snyk

Malicious Release of elementary-data PyPI Package Steals Cloud Credentials from Data Engineers

The supply chain attack on the PyPI package `elementary-data` began with a GitHub Actions script injection, leading to the malicious release of version 0.23.3 which steals cloud credentials from data engineers' environments. This critical vulnerability has a CVSS v4.0 score of 9.3. The only affected version is 0.23.3, and users must upgrade immediately to the clean version 0.23.4; impacted organizations must also rotate all potentially exposed credentials and audit their GitHub Actions workflows.
Read Full Article →

Snyk Blog In this article TL;DR What is elementary-data? How the attack unfolded Stage 1: GitHub actions script injection Stage 2: The malicious package Inside the payload: What the malware did Impact and scope Detection: Are You Affected? Step 1: Check your installed version Step 2: Check for the execution marker Step 3: Review with Snyk Remediation 1. Upgrade immediately 2. Rotate all credentials that may have been exposed 3. Clear Python caches 4. Pull clean Docker images 5. Audit your GitHub Actions workflows The repeating pattern Malicious Release of elementary-data PyPI Package Steals Cloud Credentials from Data Engineers Written by Liran Tal April 27, 2026 0 mins read A Python package on PyPI called elementary-data , with over 1 million downloads per month, has suffered a supply chain security attack sourced through a GitHub Actions attack vector. TL;DR Advisory SNYK-PYTHON-ELEMENTARYDATA-16316110 Severity Critical (CVSS v4.0: 9.3) Affected package elementary-data==0.23.3 Clean versions All versions except 0.23.3 ; upgrade to 0.23.4 Attack type Supply chain (GitHub Actions CI/CD injection, then credential-stealing package) Stolen credentials dbt profiles, Snowflake/BigQuery/Redshift creds, AWS/GCP/Azure keys, API tokens, SSH keys, .env files Scope The PyPI CLI package and a Docker Image got compromised; Elementary Cloud and the Elementary dbt package were not affected Detection marker $TMPDIR/.trinny-security-update (Linux/macOS), %TEMP%\.trinny-security-update (Windows) Disclosure April 25–26, 2026 What is elementary-data? elementary-data is a dbt-native data observability CLI tool used by data and analytics engineers to monitor pipeline health, detect anomalies, and track test failures across data warehouses like Snowflake, BigQuery, Redshift, and Databricks. The package sees roughly 280,000 downloads per week and over 1.1 million per month, placing it firmly in the tier of widely adopted data tooling. The package provides integrations with most major cloud data platforms, which is precisely what made it an attractive target. A tool that routinely handles connections to Snowflake, BigQuery, and AWS at CI/CD runtime is one that sits next to a lot of valuable credentials. How the attack unfolded The compromise occurred in two stages: first, compromising the publication pipeline; second, publishing malicious content that steals further credentials. It’s worth noting that this security incident for the elementary-data package compromise is one of the most prominent vectors recently exploited by TeamPCP and other threat actors. Stage 1: GitHub actions script injection On April 24, 2026, at 22:10 UTC, an attacker using a two-day-old GitHub account ( realtungtungtungsahur ) posted a crafted comment on PR #2147 in the elementary-data repository. The comment exploited a script injection flaw in .github/workflows/update_pylon_issue.yml , a workflow that handled issue/PR comment events. The vulnerable run: block directly interpolated ${{ github.event.comment.body }} into a shell script before bash parsing occurred. Because this expression is expanded at workflow-template time rather than sanitized as a string argument, injecting shell metacharacters or subcommands through the comment body allows arbitrary code execution in the runner. When the workflow triggered, the attacker's payload ran with the repository's GITHUB_TOKEN in scope. Critically, the attacker never needed direct write access to the repository. The GITHUB_TOKEN available to the runner had sufficient permissions to create commits, push tags, and dispatch other workflows. The injected handle_comment job stayed active for two hours and forty-six minutes, giving the attacker an extended window to set up each subsequent stage. Using the stolen token, the attacker forged a release commit with hash b1e4b1f3aad0d489ab0e9208031c67402bbb8480 . The commit was structured to look automated and official: it was an orphan commit (unreachable from any branch), authored as github-actions[bot] , carried a forged "Verified" PGP signature, and used the message release/v0.23.2 (#2188) — copied verbatim from a legitimate PR merged nine days earlier. The attacker tagged this orphan v0.23.3 and then dispatched the repository's own Release package workflow with tag=v0.23.3 as input. That workflow's checkout step used ref: ${{ inputs.tag || github.ref }} , so it was built directly from the malicious orphan commit without touching master . The legitimate CI/CD pipeline packaged and published the malicious code. By 22:20 UTC, elementary-data==0.23.3 was live on PyPI. A compromised Docker image ( ghcr.io/elementary-data/elementary:0.23.3 and :latest , digest sha256:31ecc5939de6d24cf60c50d4ca26cf7a8c322db82a8ce4bd122ebd89cf634255 ) followed four minutes later. This attack vector has appeared repeatedly in the PyPI ecosystem. The Ultralytics supply chain attack in December 2024 used the same pull_request_target injection pattern to steal credentials and publish four malicious versions. The LiteLLM compromise in early 2026 took a slightly different path (a poisoned third-party GitHub Action), but the destination was identical: stolen PyPI tokens used to publish a credential-stealing package. Stage 2: The malicious package The attacker embedded the malicious payload in a file named elementary.pth , included in the package's site-packages directory. .pth files are Python path configuration files that site.py , Python's startup module, processes automatically when the interpreter launches. Any line in a .pth file that begins with import is executed as Python code at interpreter startup, before your own code runs. This means the malware activates any time Python starts on the affected system, including during pip install operations, not just when a user explicitly imports elementary . This technique was also used in the LiteLLM v1.82.8 compromise. It is more persistent and harder to detect than embedding malicious code in __init__.py because it does not require the victim to import the poisoned package. Installing it is sufficient. Inside the payload: What the malware did The embedded code in elementary.pth was a credential stealer with three stages of encryption: a base64 outer wrapper, then XOR encryption keyed from an MD5 keystream (seed: swabag ), then a second XOR decryption layer. The obfuscation is not sophisticated by modern malware standards, but it is deliberate — it prevents trivial string-based detection of the payload and increases the time required to analyze what the package is actually doing. Once Python started on an affected machine, the decoded payload: 1. Harvested credentials and secrets across the filesystem, targeting a broad set of material: dbt profiles ( ~/.dbt/profiles.yml ) and data warehouse credentials (Snowflake, BigQuery, Redshift, Databricks). Cloud provider credentials: AWS ~/.aws/credentials plus live role credentials fetched from the IMDSv2 metadata endpoint, with direct SigV4-signed calls to AWS Secrets Manager and SSM Parameter Store; GCP application_default_credentials.json ; Azure ~/.azure/ directories. SSH private keys ( id_rsa, id_ed25519, ~/.git-credentials ). Container and orchestration secrets: ~/.docker/config.json , ~/.kube/config, all /etc/kubernetes/*.conf files, Kubernetes ServiceAccount tokens. Package manager credentials: ~/.npmrc , ~/.pypirc , ~/.cargo/credentials.toml . Other secrets at rest: .env* files (scanning up to six directory levels deep), ~/.vault-token , ~/.netrc , ~/.pgpass , ~/.my.cnf , API tokens in environment variables. Cryptocurrency wallet files (Bitcoin, Litecoin, Dogecoin, Zcash, Dash, Monero, Ripple, Ethereum, Cardano, Solana validator keypairs). System files: /etc/passwd , /etc/shadow , shell history files, /var/log/auth.log . 2. Packed all collected material into an archive named trin.tar.gz , then exfiltrated it via curl --data-binary to the C2 server at igotnofriendsonlineorirl-imgonnakmslmao.skyhanni.cloud , using the HTTP header X-Rise-To-The-Trinny: agree . 3. Left a marker file at $TMPDIR/.trinny-security-update (Linux/macOS) or %TEMP%\.trinny-security-update (Windows), indicating the malware executed at least once. The scope of credentials goes well beyond dbt and data warehouses. The payload is broadly written to sweep whatever secrets are accessible on the machine, including Kubernetes clusters, infrastructure secrets managers, and cryptocurrency keys. The dbt and warehouse targeting make it relevant to the tool's user base, but anyone running this on a developer machine or CI runner stands to lose considerably more. The credential profile is well-matched to the tool's typical users. Data engineers running the elementary-data CLI are almost certainly using it against a connected data warehouse, with cloud provider credentials, often in a CI/CD environment where those credentials are stored as secrets or environment variables. This is a targeted attack, not a generic spray. Impact and scope The attack window ran from April 24, 22:20 UTC (when the package appeared on PyPI) until the package was removed on April 25, between 8:51 and 11:51 UTC, after community members flagged the issue at 6:18 UTC. That is roughly eight to ten hours of exposure. Anyone to whom the following applies should assume the malware has executed and that their credentials have been exfiltrated: ran pip install elementary-data or upgraded during that window, used a Docker image pulled from the elementary-data registry between April 24, 22:24 UTC and removal, or had a CI/CD pipeline that automatically pulled the latest version Elementary Cloud and the Elementary dbt package were not affected, and no other CLI versions contained the malicious code. Detection: Are You Affected? Step 1: Check your installed version 1 pip show elementary-data If the output shows Version: 0.23.3 , your environment was exposed. Step 2: Check for the execution marker The malware writes a marker file on execution: 1 # Linux / macOS (checks $TMPDIR , whic

Share this article