Microsoft Names 33 Malicious npm Packages in a Dependency-Confusion Recon Campaign

Microsoft Threat Intelligence disclosed 33 malicious npm packages published under three aliases attributed to a single operator. The packages abuse dependency confusion to fingerprint developer and build environments and ship a server-toggled reconnaissance payload.

Share
Line-art split path: a package-box source with two arrows, one to a private-internal circle, one to a public-registry shelf; red dot on the public branch.

Key Takeaways

  • Microsoft Threat Intelligence disclosed 33 malicious npm packages published under three maintainer aliases — mr.4nd3r50n, ce-rwb, and t-in-one — that forensic analysis attributes to a single operator running a dependency-confusion campaign across nine organizational scopes.
  • Every package ships an obfuscated postinstall stager that beacons to oob.moika[.]tech and operates in RECON_ONLY mode by default — a deliberate two-phase architecture in which a flag toggled server-side can later upgrade fingerprinted hosts into full exploitation.
  • Engineering teams must audit dependency trees for the nine affected scopes, lock internal scopes to private registries, run npm install with --ignore-scripts, and rotate any CI/CD or cloud credentials reachable from developer or build hosts that ran any affected version on or after May 28.

Microsoft did not catch a weaponized npm wave — it caught the staging burst that precedes one, and the defender lesson is that the dependency-confusion control gap is still open in most enterprises in May 2026.

REDMOND, WASHINGTON — On May 29, 2026, Microsoft Threat Intelligence published research detailing 33 malicious npm packages registered under organizational scopes that mirror real internal corporate namespaces — a textbook dependency-confusion campaign that, on install, executes an obfuscated reconnaissance payload from a command-and-control server at oob.moika[.]tech. The packages were published in two bursts on May 28 and May 29 under three maintainer aliases — mr.4nd3r50n, ce-rwb, and t-in-one — that Microsoft's forensic analysis attributes to a single operator on the basis of shared C2 infrastructure, an identical hardcoded X-Secret HTTP header, a shared package-template generator, and matching Node.js/npm publishing toolchains.

The payload runs silently during npm install in a hard-coded RECON_ONLY mode that collects hostnames, environment variables, and developer context — but ships with a server-toggleable flag that can convert fingerprinted hosts into full exploitation targets in a follow-on phase. The Register, in parallel reporting on a separate Microsoft research post the same week, documented a related 14-package typosquatting cluster impersonating OpenSearch and Elasticsearch JavaScript libraries — making this the second npm registry compromise Microsoft has named in a 48-hour window.

Disclosure Overview
FieldDetails
DisclosureMicrosoft Threat Intelligence — Microsoft Security Blog, May 29, 2026
Campaign MechanismDependency confusion against nine organizational npm scopes that mirror real internal corporate namespaces
Packages33 malicious packages across three maintainer aliases — mr.4nd3r50n (26), ce-rwb (7), and t-in-one (12 in a May 29 second wave)
AttributionHigh-confidence single-operator attribution — shared X-Secret HTTP header, identical C2 host, matching publishing toolchain, identical package-template generator
Affected Scopes@cloudplatform-single-spa, @wb-track, @data-science, @ce-rwb, @payments-widget, @travel-autotests, @t-in-one, @capibar.chat, @sber-ecom-core
Operational ModeRECON_ONLY=1 by default — collects hostnames, environment variables, and developer context; a server-toggleable flag enables follow-on exploitation
Command and Controloob.moika[.]tech — Windows, macOS, and Linux payload endpoints; hardcoded X-Secret value l95HdDaz3kQx1Zsg3WxH6HvKANf51RY1 sent on every beacon
StatusPackages and accounts taken down by npm following Microsoft's report

What Happened

Microsoft's research describes a two-burst publishing pattern on May 28 and May 29, 2026. The first burst published 26 packages under mr.4nd3r50n (mr.4nd3r50n@yandex[.]ru) between 18:47 and 18:51 UTC on May 28, followed twelve minutes later by ce-rwb (ogvanta@yandex[.]ru) publishing seven more between 19:02 and 19:03 UTC. The second burst landed the next day, when a third account — t-in-one (t-in-one@yandex[.]ru) — published twelve more packages between 09:01:56 and 09:02:39 UTC on May 29, spanning three new scopes including @capibar.chat and @sber-ecom-core. The @sber-ecom-core/sberpay-widget package directly impersonates Sberbank's SberPay payment widget — making the financial-sector targeting explicit. Microsoft documents that the @capibar.chat/ui-kit and @sber-ecom-core/sberpay-widget scopes were pre-staged with 99.0.7 releases on May 4, weeks before the main bursts.

Every package in the cluster declares a postinstall script that runs scripts/postinstall.js — roughly 7 KB of obfuscator.io-style obfuscated JavaScript with string-array encoding, control-flow flattening, dead-code injection, and self-defending anti-tamper checks. The stager checks for the CI environment variable (silently aborting on monitored runners), validates Node.js version, hashes a per-project cache key, walks the directory tree to identify the project root, fingerprints the platform, then issues an HTTPS GET to https://oob.moika[.]tech/payload/<platform> for a binary that is written to os.tmpdir() as a .js file and spawned as a detached background process with .unref() so it outlives npm install. The May 29 wave swapped in a three-layer obfuscated 13 KB stager with a functional T_IN_ONE_NO_TELEMETRY kill switch, while preserving the same C2 host, payload endpoints, and X-Secret value.

The Lure: How Dependency Confusion Wins the Resolver

Dependency confusion is not a new technique, and Microsoft's report is a clinic in why it still works in 2026. The attacker registered packages under organizational scopes — @cloudplatform-single-spa, @sber-ecom-core, @t-in-one, and six others — that mirror real internal corporate namespaces, then set absurd version numbers (mr.4nd3r50n shipped at 100.100.100, t-in-one's headline packages at 99.5.7 and 99.5.8) so the public-registry version would win npm's default resolution against any legitimate internal release. Every package's package.json homepage, repository, and bugs fields pointed at fabricated but realistic-looking enterprise URLs — github.<scope>.io, docs.<scope>.io, jira.<scope>.io — and the README templates included a fake telemetry disclaimer designed to read past a casual code review. The combination is the dependency-confusion playbook in its mature form: name-collision plus version-inflation plus credible metadata. It defeats any organization that has not enforced scoped-registry policies at the build level.

Reconnaissance Now, Exploitation Later: The Two-Phase Design

The most operationally significant detail in Microsoft's analysis is not the volume of packages but the architecture of the payload. Each spawned binary receives four environment variables — *_RECON_ONLY, *_PKG, *_VER, and *_SECRET — and *_RECON_ONLY is hard-coded to "1" in the current campaign. Microsoft is explicit that this is the attacker's choice, not a constraint: the flag exists precisely because the architecture supports a Full exploitation mode where data exfiltration, credential theft, or backdoor installation can be enabled server-side, selectively, against hosts already fingerprinted in the reconnaissance pass. The implication for defenders is uncomfortable. The packages that were on the registry between May 28 and the takedown were not the wave — they were the survey. Any organization that installed an affected version has been profiled, and the operator now holds an inventory that can be turned into a targeting list at will. Treating the takedown as the end of the incident misreads what the takedown actually closed.

Three Aliases, One Operator, Two Years on the Pipeline

Microsoft's attribution work is unusually direct: three accounts, one operator, high confidence. The evidence is layered — the same hardcoded X-Secret value, *l95HdDaz3kQx1Zsg3WxH6HvKANf51RY1*, sent on every outbound C2 request from every package in all three accounts; the identical C2 server, *oob.moika[.]tech*; near-identical Node.js 20.20.x / npm 10.8.2 publishing toolchains; an identical package-template generator producing matching changelog entries ("Added ARM64 support", "Improved error handling") across packages; and tight temporal correlation, with a 12-minute gap between the mr.4nd3r50n and ce-rwb bursts on May 28 and a 14-hour overnight gap before t-in-one returned to expand the campaign on May 29. The mr.4nd3r50n account also carries a forensic timeline that deserves to be in the brief: its earliest package, *@cloudplatform-single-spa/logaas*, was first published in April 2024 with the keywords "Bugbounty" and "mr4nd3r50n" and the description "BugBounty testing by mr4nd3r50n". Two years later, on May 28, 2026, the same account republished the same package with the malicious obfuscated payload. The pattern echoes the broader trend documented in ESET's October 2025 to March 2026 APT activity report, which identified Lazarus's compromise of the popular axios npm package as a marquee 2026 supply-chain operation: the registry has become the soft path into the developer toolchain, and the same actors who learn it through legitimate research are some of the ones now operationalizing it.

Affected Scopes and Operator Aliases
FieldDetails
mr.4nd3r50n — 26 packagesScope @cloudplatform-single-spa; version 100.100.100; first burst 2026-05-28 18:47-18:51 UTC; original v0.0.0 of @cloudplatform-single-spa/logaas dates to April 2024 with bug-bounty keywords
ce-rwb — 7 packagesScopes @wb-track, @data-science, @ce-rwb, @payments-widget, @travel-autotests; version 3.5.22; published 2026-05-28 19:02-19:03 UTC, twelve minutes after the mr.4nd3r50n burst
t-in-one — 12 packagesScopes @t-in-one (10 credential- and token-themed names), @capibar.chat (ui-kit), @sber-ecom-core (sberpay-widget); main burst 2026-05-29 09:01:56-09:02:39 UTC; @capibar.chat and @sber-ecom-core pre-staged with 99.0.7 releases on 2026-05-04
Single-Operator IndicatorsShared X-Secret l95HdDaz3kQx1Zsg3WxH6HvKANf51RY1; identical C2 (oob.moika[.]tech); same package-template generator; matching changelog text across all packages; near-identical Node.js 20.20.x / npm 10.8.2 publishing toolchain

Scope and Impact

The exposure footprint is best understood at two layers. At the package layer, the immediate concern is any organization with a developer or build environment that resolved a dependency in one of the nine affected scopes between May 28 and the npm takedown — exposure is determined by whether internal scopes were locked to a private registry, whether dependency resolution falls back to the public npm registry by default, and whether install scripts execute. At the operator layer, the more durable concern is that any host that ran an affected version has been profiled. Microsoft documents that the payload collects hostname, platform, architecture, Node.js version, username, current working directory, project root, package name, and package version — enough to build a target list of organizations, internal scopes, and project structures keyed for selective follow-on exploitation. The defender baseline assumption should be that the operator now holds that inventory and can pivot it without ever republishing a package under the same aliases.

This is not an isolated event. The cadence of npm and broader registry compromises through May 2026 has been multiple per week, and the 33-package campaign lands in a cluster The CyberSignal has tracked closely: the TrapDoor cross-registry operation across npm, PyPI, and crates.io that poisoned AI coding assistants with prompt-injected malicious suggestions, the Packagist supply-chain compromise that hid its payload directly in package.json, the Megalodon campaign that backdoored 5,561 GitHub repositories via poisoned CI/CD workflows in a single six-hour window, the Shai-Hulud npm worm now generating valid Sigstore provenance badges for its malicious packages, and GitHub's confirmation that the TeamPCP actor exfiltrated 3,800 internal repositories through a single poisoned VS Code extension. Read together, the picture is unambiguous: the developer toolchain — registry, repository, CI/CD pipeline, IDE extension — is now the dominant 2026 supply-chain attack surface, hit by independent operators at a pace that outruns traditional patch-cycle defense.

Several specifics deserve careful framing. Microsoft does not name a nation-state or named threat group; the attribution is operator-level, not country-level. The April 2024 bug-bounty origin of the mr.4nd3r50n account is documented in npm registry metadata but does not, on its own, establish motive or trajectory beyond the two-year gap between the legitimate research version and the malicious republish. The total number of victim installs is not stated. Whether the operator has used or sold the reconnaissance inventory collected before npm's takedown is not addressed. The Register's separate reporting on the parallel 14-package OpenSearch/Elasticsearch typosquatting cluster — described in a different Microsoft research post the same week — covers a distinct campaign that Microsoft has not publicly linked to this 33-package operation; the two should be treated as separate until any such linkage is published.

Response and Attribution

For engineering organizations the immediate action is a dependency-tree audit against the nine affected scopes — @cloudplatform-single-spa, @wb-track, @data-science, @ce-rwb, @payments-widget, @travel-autotests, @t-in-one, @capibar.chat, and @sber-ecom-core — across every package-lock.json, yarn.lock, and pnpm-lock.yaml in the estate, with particular attention to the pre-staged 99.0.7 releases of @capibar.chat/ui-kit and @sber-ecom-core/sberpay-widget published on May 4. Identify every developer workstation and CI/CD runner that installed any affected version on or after May 28, and treat each as a profiled host. Rotate any AWS, HashiCorp Vault, npm access, GitHub Actions, and other CI/CD secrets reachable from those hosts. Block egress to oob.moika[.]tech, npm.t-in-one[.]io, docs.t-in-one[.]io, and jira.t-in-one[.]io at the proxy, firewall, and DNS layers. Hunt for the X-Secret HTTP header value l95HdDaz3kQx1Zsg3WxH6HvKANf51RY1 in any captured outbound traffic — Microsoft is explicit that its presence is a high-fidelity, campaign-wide indicator of compromise.

The structural fix is the one organizations keep failing to apply. Run npm install with --ignore-scripts (or set npm config set ignore-scripts true globally) so install-time hooks cannot execute. Lock every internal scope to your private registry in .npmrc so the public npm registry is never the fallback resolver for a name that should be internal. Pin known-good package versions, disable automatic dependency upgrades for any scope that shadows an internal namespace, and require approval workflows for version bumps. The npm staged-publishing and 2FA-gated release-approval changes documented earlier this cycle are an upstream control improvement; the downstream control gap — scope locking, ignore-scripts, version pinning — is what determines whether a campaign like this one reaches your build pipeline.

For SOC and threat-hunting teams, the developer-fleet hunting surface is now first-class. Pivot on postinstall-spawned reconnaissance binaries in EDR telemetry, watch for ._<scope>_init.js dropped payloads in os.tmpdir() and ~/.cache/, audit build-pipeline egress to non-build-registry destinations, and run Microsoft's published advanced-hunting queries against DeviceProcessEvents, DeviceNetworkEvents, and DeviceFileEvents tables. For CISOs, the board-level framing is straightforward: npm registry compromise is no longer an emerging threat but a routine 2026 attack vector, and the dependency-confusion control gap is one of a small number of fixes that materially changes the picture. Microsoft has not named a nation-state actor responsible for this operation; the attribution remains operator-level.


The CyberSignal Analysis

Signal 01 — This Is the Survey, Not the Wave

Most coverage of this disclosure will lead with the 33-package number, and the volume is striking. The more important detail is what the operator chose to do once the packages were installed: nothing visible. Microsoft is explicit that RECON_ONLY=1 is a flag hard-coded for this phase, not a limitation of the payload — and the architecture supports a server-toggled upgrade to full exploitation on selected hosts. That choice changes the meaning of the takedown. Removing 33 packages from the npm registry stops new infections; it does not retract the reconnaissance inventory the operator has already collected. The defender takeaway is that any organization that ran an affected version between May 28 and the takedown has been profiled, and the operator now holds a curated list of organizations, internal scopes, and project structures keyed for selective follow-on activity. Treating the npm takedown as the end of the incident is the mistake the architecture is designed to encourage.

Signal 02 — Dependency Confusion Is a Solved Problem We Have Not Solved

There is no novel tradecraft in this campaign. Dependency confusion has been documented and recommended-against since Alex Birsan's original 2021 disclosure, and the controls that defeat it — scope-locked private registries, ignore-scripts on install, version pinning, internal-name reservation — are well known. The reason a 33-package campaign in May 2026 still works is that those controls are absent or partially implemented at most enterprises. Every organization that ships JavaScript or Node.js has every internal package name that could be squatted on the public npm registry; the question is whether resolver fallback, install-script execution, and automated dependency updates are configured such that a squatted version can ever be selected on a build host. For most teams in 2026 the honest answer is still yes. That answer needs to change before the next operator runs the same playbook against a different set of scopes.

Signal 03 — The Developer Toolchain Is the 2026 Attack Surface

Read by itself, the 33-package campaign is a focused operator running a known technique against a defined set of corporate scopes. Read against the cluster it lands in — TrapDoor, Packagist, Megalodon, Shai-Hulud, TeamPCP, the Mini Shai-Hulud OpenSearch/Elasticsearch typosquatting wave, and ESET's documentation of Lazarus's axios compromise — it is one data point in what has become a defining shape of the year. The registry, the repository, the CI/CD workflow file, the IDE extension, and the package manager are all under sustained, simultaneous attack from independent operators, and the cadence has crossed the threshold from emerging-threat coverage into routine operational concern. The boardroom framing follows: npm and registry compromise is no longer a tail risk but a recurring exposure path, and the developer environment is now the highest-leverage target in the enterprise. The controls that defend it — scope locking, install-script suppression, version pinning, lockfile review, developer-fleet EDR — belong in the same baseline as patch management, identity, and endpoint protection. They are not advanced practice anymore.


Sources

TypeSource
PrimaryMicrosoft Security Blog — Malicious npm packages abuse dependency confusion to profile developer environments
ReportingThe Register — Lone attacker published 14 malicious npm packages mimicking popular OpenSearch, Elasticsearch libraries
BackgroundMicrosoft Security Blog — Typosquatted npm packages used to steal cloud and CI/CD secrets (Mini Shai-Hulud, May 28, 2026)