Unit 42 has published research that should be on every cloud security team's desk this quarter: threat actors are now systematically combining Web3 decentralized infrastructure with open-source software supply chain attacks to penetrate enterprise cloud environments. This isn't a theoretical convergence — it's an observed evolution in tradecraft, and it defeats a surprising number of the perimeter and egress controls organizations spent the last five years building.
Here's the short version: attackers are poisoning or compromising open-source packages (npm, PyPI, container images, and CI/CD dependencies), using those packages to harvest cloud credentials from developer workstations and build runners, and then hiding their command-and-control and payload staging on decentralized Web3 infrastructure — blockchain smart contracts, IPFS (InterPlanetary File System), and blockchain naming services — that traditional blocklists, domain reputation feeds, and TLS inspection were never designed to police.
The result is an attack chain with three properties defenders hate: the initial access vector is trusted code pulled by your own developers, the credential theft targets over-privileged cloud identities, and the C2 layer is censorship-resistant by design — you can't take down a smart contract, and blocking "the domain" doesn't work when the domain is one of hundreds of public IPFS gateways.
If your developers pull from public package registries and your cloud workloads use IAM roles with more than read-only permissions, you are in scope for this threat. Full stop.
Technical Analysis: How the Attack Chain Works
Phase 1 — Initial Access via the Open-Source Supply Chain
The entry point is the dependency tree. The tradecraft Unit 42 describes maps to techniques we've been tracking in live incidents for the past 18 months:
- Typosquatting and namesquatting on npm and PyPI — packages one character off from popular libraries, targeting fat-fingered installs and sloppy
package.jsonentries. - Dependency confusion — publishing public packages with the same name as internal/private packages, exploiting registry priority behavior in npm, pip, and NuGet.
- Compromised maintainer accounts — hijacking legitimate packages via credential phishing or session-token theft, then pushing malicious point releases. This is the highest-impact variant because the malicious version passes every reputation check.
- Malicious install hooks —
preinstall/postinstallscripts inpackage.jsonorsetup.pyexecution in Python packages. This is the execution primitive: the moment a developer or CI runner runsnpm install, attacker code executes with that identity's full privileges.
Phase 2 — Cloud Credential Harvesting
Once the malicious package executes on a developer workstation or, far more dangerously, a CI/CD build runner, the payload goes after cloud credentials in a predictable, scriptable order:
- Environment variables —
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_SESSION_TOKEN,AZURE_CLIENT_SECRET,GOOGLE_APPLICATION_CREDENTIALS, plus CI secrets exposed to the pipeline. - Credential files —
~/.aws/credentials,~/.aws/config,~/.azure/,~/.config/gcloud/,~/.kube/config,~/.docker/config.json,.envfiles in project directories. - Instance Metadata Service (IMDS) — HTTP requests to
169.254.169.254from build runners and workloads to steal the attached IAM role's temporary credentials. This is the single most valuable target on a compromised runner, and it's exactly why IMDSv2 enforcement matters (more on that in remediation). - Source control secrets — tokens in
~/.git-credentials,~/.npmrc(_authToken),~/.pypirc, and SSH keys — which enable lateral movement back into the supply chain to poison additional packages.
The harvested credentials are then used against cloud APIs from attacker infrastructure — often showing up in CloudTrail as GetCallerIdentity, ListBuckets, ListSecrets, and GetSecretValue calls from ASNs and geographies with no business touching your environment.
Phase 3 — Web3 as C2 and Payload Infrastructure ("EtherHiding" and Beyond)
This is the evolution the Unit 42 report highlights, and it's the part that breaks legacy detection assumptions:
- Smart-contract-hosted C2 (EtherHiding): Malware queries a public blockchain (BNB Smart Chain and Ethereum are the most commonly abused) via JSON-RPC, reads attacker-controlled data stored in a contract transaction or storage slot, and decodes it into the next-stage payload or C2 address. There is no domain to sinkhole and no server to seize — the blockchain is the dead drop. Takedown requires the attacker to lose their private key, not the defender to file an abuse ticket.
- IPFS payload staging: Second-stage payloads hosted on IPFS and fetched through public HTTP gateways (
ipfs.io,cloudflare-ipfs.com,gateway.pinata.cloud,dweb.link, and dozens of others). Each gateway is a legitimate, high-reputation domain. Blocking one does nothing; blocking all of them is feasible but rarely done. - Blockchain Naming Services (BNS/Ethereum Name Service): C2 domains registered as
.ethor similar, resolved through specialized gateways, evading conventional DNS reputation and registrar takedown.
From a defender's seat, the observable behaviors are: a Node.js or Python process making outbound HTTPS to a blockchain RPC endpoint or IPFS gateway — something no legitimate build step should ever do — and non-cloud processes reading cloud credential stores.
Affected Platforms and Exposure
- Package ecosystems: npm, PyPI (and by extension, any ecosystem allowing install-time code execution)
- Build infrastructure: GitHub Actions, GitLab CI, Jenkins, CircleCI, Azure DevOps runners — especially self-hosted runners with attached cloud IAM roles
- Cloud platforms: AWS, Azure, GCP — the credential theft and API abuse is provider-agnostic
- Endpoints: Developer workstations (Windows, macOS, Linux) where dependency installation occurs
Exploitation Status
Per Unit 42's reporting, this is observed, active tradecraft in current campaigns — not a proof of concept. There is no single CVE to patch because this is architectural abuse of trusted ecosystems and protocols, not a memory-corruption bug. That is precisely what makes it dangerous: there is no patch Tuesday for "npm executes your install scripts" or "your build runner has an internet-routable path to the metadata service." Defense is entirely about configuration, segmentation, and behavioral detection.
Detection & Response
The detection strategy has to focus on the two chokepoints every variant of this attack must cross: (1) install-time code execution doing something no build should do, and (2) access to cloud credentials or metadata services by processes that have no business touching them. Network detection on Web3 infrastructure is a valuable third layer, tuned to developer/build contexts to control false positives.
Sigma Rules
The following rules target the highest-fidelity behaviors. Rule 1 catches install hooks reaching for the network or credential stores — the single loudest signal in this chain. Rule 2 catches non-cloud processes touching credential files or the metadata service. Rule 3 provides network-layer detection for Web3 C2/staging from build and development processes.
---
title: Package Manager Install Hook Spawning Network or Credential Access
description: Detects npm, node, pip, or python processes spawning shells or download utilities during package installation — consistent with malicious preinstall/postinstall hooks used in supply chain attacks.
references:
- https://unit42.paloaltonetworks.com/web3-cloud-supply-chain-attacks/
- https://attack.mitre.org/techniques/T1195/002/
author: Security Arsenal
date: 2026/04/06
status: experimental
tags:
- attack.initial_access
- attack.t1195.002
- attack.execution
- attack.t1059
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|endswith:
- '\node.exe'
- '\npm.cmd'
- '\npm.exe'
- '\python.exe'
- '\pip.exe'
selection_child:
Image|endswith:
- '\cmd.exe'
- '\powershell.exe'
- '\pwsh.exe'
- '\curl.exe'
- '\wget.exe'
- '\certutil.exe'
- '\bitsadmin.exe'
filter_known_builds:
CommandLine|contains:
- 'node-gyp'
- 'node-pre-gyp'
condition: selection_parent and selection_child and not filter_known_builds
falsepositives:
- Native module compilation (node-gyp) during legitimate installs — tune per build environment
level: high
---
title: Cloud Credential Store Access by Non-Cloud Process
description: Detects processes other than cloud CLIs and credential helpers accessing AWS, Azure, GCP, or kubeconfig credential stores — consistent with post-compromise credential harvesting by malicious packages.
references:
- https://unit42.paloaltonetworks.com/web3-cloud-supply-chain-attacks/
- https://attack.mitre.org/techniques/T1552/001/
author: Security Arsenal
date: 2026/04/06
status: experimental
tags:
- attack.credential_access
- attack.t1552.001
- attack.t1552.005
logsource:
category: file_event
product: windows
detection:
selection_paths:
TargetFilename|contains:
- '\.aws\credentials'
- '\.aws\config'
- '\.azure\'
- '\.config\gcloud\'
- '\.kube\config'
- '\.npmrc'
- '\.pypirc'
- '\.git-credentials'
- '\.docker\config.json'
filter_legit:
Image|endswith:
- '\aws.exe'
- '\az.exe'
- '\gcloud.exe'
- '\kubectl.exe'
- '\git.exe'
- '\docker.exe'
- '\code.exe'
condition: selection_paths and not filter_legit
falsepositives:
- Backup software, EDR scanners, IDE plugins — baseline and exclude by hash where possible
level: high
---
title: Web3 or IPFS Infrastructure Contacted by Build or Scripting Process
description: Detects node, python, or shell processes initiating DNS resolution or connections to public IPFS gateways or blockchain JSON-RPC endpoints — indicative of EtherHiding-style C2 or decentralized payload staging.
references:
- https://unit42.paloaltonetworks.com/web3-cloud-supply-chain-attacks/
- https://attack.mitre.org/techniques/T1071/001/
author: Security Arsenal
date: 2026/04/06
status: experimental
tags:
- attack.command_and_control
- attack.t1071.001
- attack.t1102
logsource:
category: dns
product: windows
detection:
selection:
query|contains:
- 'ipfs.io'
- 'dweb.link'
- 'gateway.pinata.cloud'
- 'cloudflare-ipfs.com'
- 'w3s.link'
- 'bsc-dataseed'
- 'mainnet.infura.io'
- 'eth-mainnet'
- 'rpc.ankr.com'
filter_web3_devs:
Image|endswith:
- '\chrome.exe'
- '\firefox.exe'
- '\msedge.exe'
condition: selection and not filter_web3_devs
falsepositives:
- Legitimate Web3/dApp development teams — scope to non-development subnets or maintain an allowlist of approved project RPC endpoints
level: medium
KQL Hunt — Microsoft Sentinel / Defender
This query hunts for the intersection of build tooling and suspicious outbound behavior: Node/Python processes spawning download utilities, touching credential stores, or reaching Web3/IPFS infrastructure. Run it across a 14-day lookback and pivot on any host that fires more than one clause.
// Hunt: Web3/Supply-Chain compromise behaviors on build & dev endpoints
let Lookback = 14d;
let SuspiciousRemoteHosts = dynamic([
"ipfs.io", "dweb.link", "gateway.pinata.cloud", "cloudflare-ipfs.com",
"w3s.link", "bsc-dataseed.binance.org", "mainnet.infura.io", "rpc.ankr.com"
]);
let CredentialPaths = dynamic([
".aws/credentials", ".aws\\credentials", ".azure", "gcloud",
".kube/config", ".npmrc", ".pypirc", ".git-credentials", "169.254.169.254"
]);
union isfuzzy=true
(
// Package managers spawning shells/downloaders or touching credential stores
DeviceProcessEvents
| where Timestamp > ago(Lookback)
| where InitiatingProcessFileName in~ ("node.exe", "npm.cmd", "npm", "python.exe", "pip", "pip3", "sh", "bash")
| where FileName in~ ("powershell.exe", "pwsh.exe", "cmd.exe", "curl.exe", "wget.exe", "curl", "wget", "certutil.exe")
or ProcessCommandLine has_any (CredentialPaths)
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine, InitiatingProcessCommandLine
),
(
// Outbound connections to Web3/IPFS infrastructure from scripting processes
DeviceNetworkEvents
| where Timestamp > ago(Lookback)
| where RemoteUrl has_any (SuspiciousRemoteHosts) or RemoteIP in ("169.254.169.254")
| where InitiatingProcessFileName in~ ("node.exe", "node", "python.exe", "python", "curl", "wget", "powershell.exe", "npm")
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteUrl, RemoteIP, RemotePort
)
| sort by Timestamp desc
For Syslog-ingested Linux build runners, add a parallel hunt against Syslog and CommonSecurityLog for egress to *.ipfs.*, bsc-dataseed*, or infura.io sourced from CI subnets — legitimate Web3 RPC traffic from production infrastructure should be exactly zero in most enterprises.
Velociraptor VQL — Endpoint Forensic Hunt
Deploy this as a hunt across developer and build-runner assets. It identifies package-manager parent processes whose children are shells or download tools, and flags processes holding open handles to credential stores.
-- Hunt: Malicious install hooks & credential harvesting (Web3 supply chain)
SELECT Pid, Ppid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE
(
-- Package managers spawning shells, downloaders, or script interpreters
(Name =~ '(?i)node|npm|python|pip' AND
CommandLine =~ '(?i)powershell|cmd\.exe|/bin/(ba)?sh|curl|wget|base64|nc ')
)
OR
(
-- Any process referencing cloud credential stores or metadata service
CommandLine =~ '(?i)\.aws/credentials|\.azure/|gcloud|\.kube/config|\.npmrc|\.pypirc|169\.254\.169\.254|latest/meta-data'
AND NOT Exe =~ '(?i)aws|az(\.exe)?$|gcloud|kubectl|terraform'
)
OR
(
-- Processes reaching Web3/IPFS infrastructure
CommandLine =~ '(?i)ipfs\.io|dweb\.link|pinata|bsc-dataseed|infura\.io|eth-mainnet|web3|ethers'
AND NOT Name =~ '(?i)chrome|firefox|msedge'
)
Hardening & Verification Script
This Bash script is built for CI/CD runners and Linux/macOS developer workstations. It (1) audits for dangerous install hooks in the dependency tree, (2) verifies npm is configured to not execute install scripts by default, (3) tests whether IMDS is reachable and whether IMDSv2 is enforced on AWS EC2, and (4) checks for egress to common IPFS gateways. Run it as a scheduled job on build fleets and gate pipeline promotion on its findings.
#!/bin/bash
# Web3 Supply-Chain Hardening Audit — Security Arsenal
# Run on CI/CD runners and developer Linux/macOS workstations.
set -uo pipefail
FAIL=0
echo "=== [1/5] Auditing install hooks in dependency manifests ==="
for f in package.json; do
find . -name "$f" -not -path '*/node_modules/*' 2>/dev/null | while read -r pkg; do
if grep -Eq '"(preinstall|postinstall|install)"' "$pkg"; then
echo "[!] Install hook found in $pkg:"
grep -E '"(preinstall|postinstall|install)"' "$pkg"
fi
done
done
echo "=== [2/5] Checking npm global config for script execution ==="
if command -v npm >/dev/null 2>&1; then
npm config get ignore-scripts | grep -q true \
&& echo "[+] npm ignore-scripts=true (install hooks disabled)" \
|| { echo "[!] npm ignore-scripts is NOT true — set it: npm config set ignore-scripts true"; FAIL=1; }
fi
echo "=== [3/5] Testing Instance Metadata Service exposure (AWS) ==="
if curl -s -m 2 -o /dev/null -w '%{http_code}' http://169.254.169.254/latest/meta-data/ 2>/dev/null | grep -q 200; then
echo "[!] IMDSv1 is REACHABLE — token-less metadata access possible. Enforce IMDSv2."
FAIL=1
elif curl -s -m 2 -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 60" \
http://169.254.169.254/latest/api/token 2>/dev/null | grep -q .; then
echo "[+] IMDSv2 enforced (token required)."
else
echo "[+] Metadata service not reachable from this host (or not EC2)."
fi
echo "=== [4/5] Testing egress to public IPFS / blockchain RPC infrastructure ==="
for host in ipfs.io dweb.link gateway.pinata.cloud bsc-dataseed.binance.org; do
if curl -s -m 3 -o /dev/null "https://$host" 2>/dev/null; then
echo "[!] Egress to $host is ALLOWED — block at egress proxy/firewall for build fleets."
FAIL=1
else
echo "[+] Egress to $host blocked."
fi
done
echo "=== [5/5] Checking for overly permissive cloud credential files ==="
for cred in "$HOME/.aws/credentials" "$HOME/.npmrc" "$HOME/.kube/config"; do
if [ -f "$cred" ]; then
perms=$(stat -c '%a' "$cred" 2>/dev/null || stat -f '%Lp' "$cred")
[ "$perms" -le 600 ] 2>/dev/null \
&& echo "[+] $cred permissions OK ($perms)" \
|| { echo "[!] $cred too permissive ($perms) — chmod 600 $cred"; FAIL=1; }
fi
done
echo "=== Audit complete. FAIL=$FAIL ==="
exit $FAIL
Remediation: Breaking the Chain at Its Weakest Links
There is no patch for this class of attack — remediation is architectural. Prioritize in this order, because this is the order attackers exploit.
1. Kill install-time code execution where you can.
Set ignore-scripts=true globally for npm (npm config set ignore-scripts true in CI images and developer dotfiles). For the small set of packages that legitimately need native builds (e.g., node-gyp consumers), maintain an explicit allowlist via .npmrc ignore-scripts=false scoped per-project, reviewed in code review. For Python, prefer wheels over sdists and block setup.py install paths in your private registry proxy.
2. Enforce IMDSv2 and hop-limit 1 on every EC2 instance and build runner.
aws ec2 modify-instance-metadata-options --http-tokens required --http-put-response-hop-limit 1. Add a CloudTrail/Config detective control flagging any instance launched without HttpTokens: required. On non-AWS runners, firewall the link-local metadata range (169.254.169.254) from build job network namespaces — GitHub Actions and GitLab both document this.
3. Eliminate long-lived cloud credentials from humans and pipelines.
Move CI/CD to OIDC-based workload identity federation (GitHub Actions → AWS sts:AssumeRoleWithWebIdentity, Azure workload identity federation, GCP Workload Identity). A stolen OIDC token expires in minutes; a stolen AWS_SECRET_ACCESS_KEY in a developer's home directory is valid until you find it. Where static keys must exist, scope them to least privilege and alert on any use from an unrecognized ASN.
4. Gate your package supply chain.
Route all npm/PyPI traffic through a private registry proxy (Artifactory, Nexus, CodeArtifact, Artifact Registry) with: quarantine periods for newly published versions, namespace protection against dependency confusion (reserve your internal package names in public registries), SCA scanning with malicious-package intelligence feeds, and lockfile integrity enforcement (npm ci, never npm install in CI).
5. Block Web3 staging infrastructure at egress. Denylist public IPFS gateways and public blockchain RPC endpoints at the egress proxy for all non-development segments, and alert on any hits from build subnets. Maintain an explicit allowlist for genuine Web3 engineering teams. Add the gateway domains from the Sigma rule above to your threat intel feeds and DNS security layer — and treat any IPFS gateway fetch from a build runner as a P2 incident.
6. Detect the API-side blast radius.
Alert in CloudTrail/Azure Activity Log/Cloud Audit Logs for GetCallerIdentity, ListSecrets, GetSecretValue, and ListBuckets from non-corporate ASNs, and for IAM credential use where the userAgent doesn't match your known tooling. Stolen keys are almost always validated with GetCallerIdentity within minutes — that's your cheapest tripwire.
7. If you suspect compromise: treat it as a full credential-exposure incident, not a malware cleanup. Rotate every secret reachable from the affected context (cloud keys, registry tokens, SSH keys, CI secrets), review CloudTrail back to the dependency-install timestamp, and audit any packages the compromised identity could have published — supply chain breaches propagate downstream.
The Bottom Line
The Unit 42 research documents a maturation, not a novelty: attackers have industrialized the path from npm install to your cloud control plane, and Web3 infrastructure gives them a C2 layer that traditional takedown and blocklist economics can't touch. The defenders who win here are the ones who stop treating the build pipeline as a trusted zone. Disable install scripts, kill static credentials, lock down the metadata service, and watch for your own tooling talking to infrastructure it has no business knowing about. Every one of those controls is cheap. The incident you're preventing is not.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.