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 and securing the packages.
Key outcome: StepSecurity's AI-powered detection caught the supply chain attack early, enabling rapid remediation. The compromised versions were deprecated the same day they were reported.
The Compromised Packages
Both packages are widely used in React Native mobile applications for phone number input and country selection functionality:
- react-native-international-phone-number — compromised version:
0.11.8, last clean version:0.11.7, ~92,000 monthly downloads - react-native-country-select — compromised version:
0.3.91, last clean version:0.3.9, ~42,000 monthly downloads
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.
StepSecurity Detection and Response
StepSecurity's AI Package Analyst continuously monitors the npm registry for suspicious package releases. It flagged both compromised versions automatically based on multiple signals:
- New versions published directly to npm with no corresponding GitHub release
- Addition of preinstall scripts that were not present in previous versions
- Heavily obfuscated code in the newly added
install.js - Version numbering anomalies (
0.3.91appearing to mimic0.3.9)
Timeline
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 — 1:15 PM UTC
Maintainer (@AstrOOnauta) responds and deprecates both compromised versions
From detection to maintainer action: approximately 1.5 hours.
AI Package Analyst Reports
StepSecurity's AI Package Analyst generated detailed analysis reports for both packages, which were linked directly in the GitHub issues:
- AI Package Analyst Report: react-native-international-phone-number@0.11.8
- AI Package Analyst Report: react-native-country-select@0.3.91




Immediate Action: StepSecurity Filed Issues in the Repos
As soon as the AI Package Analyst flagged the compromised versions, StepSecurity immediately created detailed security issues in both affected repositories. Each issue included:
- Clear evidence of the compromise, including links to the npm diffs
- Links to the AI Package Analyst reports with full analysis
- Step-by-step remediation guidance for the maintainer, including how to deprecate the malicious versions and secure the npm account
- Cross-references between the two related compromises
The issues were filed by @sailikhith-stepsecurity, part of StepSecurity's threat intelligence team.
"Thanks for it, I deprecated the version!!!"
— @AstrOOnauta, package maintainer
How the Attack Worked
The attacker gained the ability to publish new versions to npm — likely through a compromised npm token — and published malicious releases that bypassed the normal GitHub release process entirely. Neither compromised version had a corresponding GitHub release or tag. The gitHead field for react-native-international-phone-number@0.11.8 is identical to v0.11.7, confirming the malicious package was not built from any new source commit.
Stage 1 — Preinstall Hook
Both compromised versions added an install.js file executed as a preinstall script:
"scripts": {
"preinstall": "node install.js"
}
This runs automatically on every npm install, before any other package code runs. The victim needs only to install the package — there is no need to import or run anything. The install.js file is heavily obfuscated using RC4-based string encryption and array rotation (a pattern common to the javascript-obfuscator toolchain).
Stage 2 — Geo-Filter: Skipping Russian Victims
After a 10-second startup delay, the malware checks whether the victim is located in Russia by inspecting:
- The
LANG,LANGUAGE, andLC_ALLenvironment variables forru_RU/Russian - The OS username and system timezone (against a hardcoded list of Russian timezones:
Europe/Moscow,Asia/Krasnoyarsk,Asia/Vladivostok,MSK, and 9 others) - The UTC offset (skips if between +2 and +12)
If any match, the script exits silently. This is a well-known technique used by Russian-origin malware to avoid attacking compatriots and reduce exposure to domestic law enforcement.
Stage 3 — Solana Blockchain as Dead-Drop C2
Rather than hardcoding a payload URL (which would be trivially blocked), the attacker uses the Solana blockchain as a censorship-resistant command-and-control resolver.
The malware polls a hardcoded Solana wallet address:
6YGcuyFRJKZtcaYCCFba9fScNUvPkGXodXE1mJiSzqDJ
It calls the getSignaturesForAddress JSON-RPC method, trying nine public Solana RPC endpoints as fallbacks (including api.mainnet-beta.solana.com, rpc.ankr.com/solana, and others). The attacker posts a transaction to their own wallet with a Solana Memo Program message containing a base64-encoded payload URL. This means the attacker can silently rotate their payload server at any time — simply by posting a new transaction — without ever touching the malware binary.
Stage 4 — Payload Delivery
With the URL in hand, the malware issues an HTTP GET to the attacker's server at http://45.32.150.251/. The OS type (Linux, Darwin, or Windows_NT) is sent as an os HTTP header, allowing the server to deliver platform-specific payloads. The server response carries the stage-2 payload (base64-encoded and AES-encrypted), with the AES decryption key and IV delivered via HTTP response headers.
Stage 5 — In-Memory Execution
The decrypted payload is executed entirely in memory, never written to disk, via eval() on macOS/Linux or a Node.js vm.Script sandbox on other platforms. A persistence lock is written to ~/init.json with the current timestamp; the malware will not re-execute within a 48-hour window on the same machine.
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
linkfield for payload URL delivery - Russia geo-filter — identical timezone and locale checks
~/init.json48-hour persistence lock- Payload server on Vultr IP space —
45.32.150.251falls in the same45.32.150.xblock 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.
Indicators of Compromise
- 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) - npm anomaly fingerprint:
preinstallscriptnode install.js, build environment Node 22.22.0 / npm 10.9.4, ~19 KB size increase
What You Should Do
If you use these packages
- Check your
package-lock.jsonoryarn.lockfor versionsreact-native-international-phone-number@0.11.8orreact-native-country-select@0.3.91 - If either version is present, remove
node_modulesand reinstall to get a clean version - Audit your systems — if the compromised version was installed, the
preinstallscript executed on your machine. Rotate any credentials and tokens that may have been accessible - Pin to known clean versions:
0.11.7forreact-native-international-phone-numberand0.3.9forreact-native-country-select
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 affected packages. Upon being notified, he responded promptly and professionally — deprecating the malicious versions and publishing clean replacements within approximately 90 minutes of our reports. His quick action limited the potential blast radius of this attack significantly.
The swift resolution of this incident is a reminder of what's possible when security researchers and open-source maintainers work together in good faith.
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.91andreact-native-international-phone-number@0.11.8would 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.


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.
References
- GitHub Issue: Malicious npm Release Detected in react-native-international-phone-number v0.11.8
- GitHub Issue: Malicious npm Release Detected in react-native-country-select v0.3.91
- StepSecurity AI Package Analyst: react-native-international-phone-number@0.11.8
- StepSecurity AI Package Analyst: react-native-country-select@0.3.91
- npm diff: react-native-international-phone-number 0.11.7 vs 0.11.8
- npm diff: react-native-country-select 0.3.9 vs 0.3.91


