# oob.moika.tech dependency-confusion campaign across nine npm scopes (mr.4nd3r50n / ce-rwb / t-in-one)

> Between 2026-05-28 18:47 UTC and 2026-05-29 09:02 UTC a single operator using the npm aliases `mr.4nd3r50n`, `ce-rwb`, and `t-in-one` pushed dependency-confusion packages across nine corporate-looking scopes (`@cloudplatform-single-spa`, `@t-in-one`, `@ce-rwb`, `@wb-track`, `@data-science`, `@payments-widget`, `@travel-autotests`, `@capibar.chat`, `@sber-ecom-core`). Postinstall stagers exfiltrate `process.env` to `oob.moika[.]tech` with a shared `X-Secret` header.

- Published: 2026-05-28
- Last updated: 2026-05-29
- Severity: high
- Kind: Dependency confusion - A package published on the public registry under a name guessed from a company's private registry, usually at a sentinel version such as 0.0.0 or 99.99.0, so a misconfigured resolver pulls it instead of the internal one. Many are bug-bounty or penetration-test probes whose only payload is a beacon with the hostname.
- Ecosystems: npm
- Scope: 45 packages, 47 compromised versions
- Tags: dependency-confusion, credential-theft, obfuscation, infostealer
- Also known as: mr.4nd3r50n campaign, oob.moika.tech, t-in-one
- Detected by: Microsoft Threat Intelligence, SafeDep
- Incident ID: npm-2026-05-28-moika-dependency-confusion

## Affected packages (45)

Only the exact versions listed were named by the source advisories. Other versions are not implicated.

| Package | Ecosystem | Compromised versions |
|---|---|---|
| [@capibar.chat/ui-kit](https://dependencywatch.io/package/npm/@capibar.chat/ui-kit) | npm | 99.0.7, 99.5.7 |
| [@ce-rwb/ce-tools-editor-admin](https://dependencywatch.io/package/npm/@ce-rwb/ce-tools-editor-admin) | npm | 3.5.22 |
| [@ce-rwb/ce-tools-editor-core](https://dependencywatch.io/package/npm/@ce-rwb/ce-tools-editor-core) | npm | 3.5.22 |
| [@ce-rwb/ce-tools-editor-render](https://dependencywatch.io/package/npm/@ce-rwb/ce-tools-editor-render) | npm | 3.5.22 |
| [@cloudplatform-single-spa/administration](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/administration) | npm | 100.100.100 |
| [@cloudplatform-single-spa/arenadata-db](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/arenadata-db) | npm | 100.100.100 |
| [@cloudplatform-single-spa/base-static-page](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/base-static-page) | npm | 100.100.100 |
| [@cloudplatform-single-spa/business-solutions](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/business-solutions) | npm | 100.100.100 |
| [@cloudplatform-single-spa/cloud-dns](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/cloud-dns) | npm | 100.100.100 |
| [@cloudplatform-single-spa/cnapp-ui](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/cnapp-ui) | npm | 100.100.100 |
| [@cloudplatform-single-spa/cp-api-gw](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/cp-api-gw) | npm | 100.100.100 |
| [@cloudplatform-single-spa/datagrid](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/datagrid) | npm | 100.100.100 |
| [@cloudplatform-single-spa/dataplatform](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/dataplatform) | npm | 100.100.100 |
| [@cloudplatform-single-spa/dataplatform-metastore](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/dataplatform-metastore) | npm | 100.100.100 |
| [@cloudplatform-single-spa/dataplatform-trino](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/dataplatform-trino) | npm | 100.100.100 |
| [@cloudplatform-single-spa/employees](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/employees) | npm | 100.100.100 |
| [@cloudplatform-single-spa/enterprise](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/enterprise) | npm | 100.100.100 |
| [@cloudplatform-single-spa/floating-ips](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/floating-ips) | npm | 100.100.100 |
| [@cloudplatform-single-spa/logaas](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/logaas) | npm | 100.100.100 |
| [@cloudplatform-single-spa/marketplace-gigachat](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/marketplace-gigachat) | npm | 100.100.100 |
| [@cloudplatform-single-spa/ml-ai-agents-agent](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/ml-ai-agents-agent) | npm | 100.100.100 |
| [@cloudplatform-single-spa/ml-ai-agents-agent-system](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/ml-ai-agents-agent-system) | npm | 100.100.100 |
| [@cloudplatform-single-spa/monitoring](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/monitoring) | npm | 100.100.100 |
| [@cloudplatform-single-spa/security-groups](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/security-groups) | npm | 100.100.100 |
| [@cloudplatform-single-spa/ssh-keys](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/ssh-keys) | npm | 100.100.100 |
| [@cloudplatform-single-spa/support](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/support) | npm | 100.100.100 |
| [@cloudplatform-single-spa/svp-baas](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/svp-baas) | npm | 100.100.100 |
| [@cloudplatform-single-spa/svp-interfaces](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/svp-interfaces) | npm | 100.100.100 |
| [@cloudplatform-single-spa/svp-s3-storage](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/svp-s3-storage) | npm | 100.100.100 |
| [@cloudplatform-single-spa/vpn](https://dependencywatch.io/package/npm/@cloudplatform-single-spa/vpn) | npm | 100.100.100 |
| [@data-science/llm](https://dependencywatch.io/package/npm/@data-science/llm) | npm | 3.5.22 |
| [@payments-widget/payments-widget-sdk](https://dependencywatch.io/package/npm/@payments-widget/payments-widget-sdk) | npm | 3.5.22 |
| [@sber-ecom-core/sberpay-widget](https://dependencywatch.io/package/npm/@sber-ecom-core/sberpay-widget) | npm | 99.0.7, 99.5.8 |
| [@t-in-one/add_app_middleware_token](https://dependencywatch.io/package/npm/@t-in-one/add_app_middleware_token) | npm | 5.7.1 |
| [@t-in-one/add_application](https://dependencywatch.io/package/npm/@t-in-one/add_application) | npm | 5.7.1 |
| [@t-in-one/add_application_service_token](https://dependencywatch.io/package/npm/@t-in-one/add_application_service_token) | npm | 5.7.1 |
| [@t-in-one/add_application_tid](https://dependencywatch.io/package/npm/@t-in-one/add_application_tid) | npm | 5.7.1 |
| [@t-in-one/application_id_storage_key_token](https://dependencywatch.io/package/npm/@t-in-one/application_id_storage_key_token) | npm | 5.7.1 |
| [@t-in-one/form_product_token](https://dependencywatch.io/package/npm/@t-in-one/form_product_token) | npm | 5.7.1 |
| [@t-in-one/get_application_hid](https://dependencywatch.io/package/npm/@t-in-one/get_application_hid) | npm | 5.7.1 |
| [@t-in-one/only_difference_payload](https://dependencywatch.io/package/npm/@t-in-one/only_difference_payload) | npm | 5.7.1 |
| [@t-in-one/prefill_bundle_data_token](https://dependencywatch.io/package/npm/@t-in-one/prefill_bundle_data_token) | npm | 5.7.1 |
| [@t-in-one/prefill_credit_data_token](https://dependencywatch.io/package/npm/@t-in-one/prefill_credit_data_token) | npm | 5.7.1 |
| [@travel-autotests/npm-proto](https://dependencywatch.io/package/npm/@travel-autotests/npm-proto) | npm | 3.5.22 |
| [@wb-track/shared-front](https://dependencywatch.io/package/npm/@wb-track/shared-front) | npm | 3.5.22 |

## What happened

Microsoft Threat Intelligence published an analysis on 2026-05-29 of an active dependency-confusion campaign in which one operator - split across the three npm publisher aliases `mr.4nd3r50n` (`mr.4nd3r50n@yandex[.]ru`), `ce-rwb` (`ogvanta@yandex[.]ru`), and `t-in-one` (`t-in-one@yandex[.]ru`) - pushed malicious packages under nine corporate-looking npm scopes across two publishing bursts on 2026-05-28 and 2026-05-29. All packages share the same obfuscated `scripts/postinstall.js` stager, the same C2 (`oob.moika[.]tech`), and the same authentication marker (`X-Secret: l95HdDaz3kQx1Zsg3WxH6HvKANf51RY1`), confirming a single operator.

The `mr.4nd3r50n` account opened the campaign at 18:47–18:51 UTC on 2026-05-28 with 26 packages under `@cloudplatform-single-spa`, all stamped version `100.100.100` to win semver resolution against a real internal scope. Eleven minutes later, the `ce-rwb` account dropped 7 packages under `@wb-track`, `@data-science`, `@ce-rwb`, `@payments-widget`, and `@travel-autotests` at version `3.5.22`. The next morning at 09:01:56–09:02:39 UTC, `t-in-one` published 10 `@t-in-one` packages in a 43-second automated burst at version `5.7.1`, plus follow-ons under `@capibar.chat/ui-kit` (`99.5.7`) and `@sber-ecom-core/sberpay-widget` (`99.5.8`). Two of those scopes had a pre-staged `99.0.7` release on 2026-05-04, suggesting weeks of reconnaissance against a Russian-language fintech / chat-platform target before the live burst.

The execution chain is straightforward but well-designed for stealth: npm `install` triggers `scripts/postinstall.js` (a ~7–13 KB obfuscated stager), which performs an HTTPS GET to `oob.moika[.]tech` carrying the shared `X-Secret` header, writes an OS-specific second-stage payload (`oob.moika[.]tech/payload/{win,mac,linux}`) into `tmpdir` as `._<scope>_init.js`, then spawns it as a detached child process with `windowsHide=true`. The payload is cached under `~/.cache/._<scope>_init/` for re-use and exfiltrates the runner's full `process.env`. A `*_RECON_ONLY=1` flag is hard-coded in the current builds, meaning the operator is still in the reconnaissance phase - orgs that saw a callback to `oob.moika[.]tech` should treat that environment as enumerated and expect a targeted follow-on.

Microsoft's blog tracks 33 packages across the May 28–29 publishing bursts. SafeDep separately reported a larger 164-package wave on 2026-05-27 against `@cloudplatform-single-spa`, `@mlspace`, `@car-loans`, `@fb-deposit`, and `@debit-ib` at version `99.99.99`, exfiltrating to the same `oob.moika[.]tech/report` endpoint - strong evidence that the same operator was active for at least 48 hours before Microsoft's disclosure. The SafeDep package-level inventory could not be re-verified at ingest time so only the Microsoft-confirmed 45 package versions are encoded below; treat the SafeDep scopes as additional hunting hints.

- Microsoft Defender detections: `Trojan:JS/ObfusNpmJs.SA` and `Trojan:JS/ObfusNpmJs` cover the obfuscated postinstall stager and on-disk recon payload.
- The `mr.4nd3r50n` alias was previously observed in April 2024 publishing what appeared to be benign bug-bounty dependency-confusion proofs; the same handle returning two years later with a production-quality C2 and a 33-package burst is itself notable tradecraft signal.
- All Yandex.ru maintainer addresses, the spoofed `t-in-one[.]io` infrastructure, and the SafeDep Russian-language scopes (`@sber-ecom-core`, `@capibar.chat`, `@fb-deposit`, `@debit-ib`) point at Russian-language targets, though Microsoft does not formally attribute.

## Impact

- Postinstall hook dumps full `process.env` to `https://oob.moika[.]tech/report` - npm tokens, AWS/GCP/Azure keys, GitHub tokens, DB URLs all leak from any CI runner or dev workstation that installed a package
- Stager downloads OS-specific second-stage payloads from `oob.moika[.]tech/payload/{win,mac,linux}` and spawns them as detached background processes (`windowsHide=true`)
- Hard-coded `*_RECON_ONLY=1` flag means current payloads are reconnaissance-only - affected orgs should expect a follow-on intrusion attempt against any environment that pinged the C2
- Spoofed `package.json` URLs reference real-looking internal GitHub Enterprise, Jira, and docs portals (e.g. `npm.t-in-one[.]io`, `docs.t-in-one[.]io`, `jira.t-in-one[.]io`) so reviewers skimming metadata see a plausible "internal package"
- Two `@capibar.chat` / `@sber-ecom-core` builds were pre-staged on 2026-05-04 as version `99.0.7`, indicating reconnaissance against a Russian-language fintech / chat-platform target for several weeks before the burst

## What to do

1. Audit every `package.json`, lockfile, and CI cache for the scopes `@cloudplatform-single-spa`, `@t-in-one`, `@ce-rwb`, `@wb-track`, `@data-science`, `@payments-widget`, `@travel-autotests`, `@capibar.chat`, `@sber-ecom-core` - see the packages map below for the exact name set
2. Block outbound to `oob.moika[.]tech`, `npm.t-in-one[.]io`, `docs.t-in-one[.]io`, `jira.t-in-one[.]io` and hunt for HTTP requests carrying header `X-Secret: l95HdDaz3kQx1Zsg3WxH6HvKANf51RY1`
3. Rotate every secret that could have been in `process.env` on any host that installed one of these packages: npm tokens, GitHub PATs, AWS/GCP/Azure keys, database URLs, signing keys
4. Enforce scope ownership for internal packages: register every internal `@scope` on the public npm registry (even with a stub) and pin private mirrors so the public version cannot be resolved
5. Run `npm ci --ignore-scripts` (or pnpm / yarn equivalents) in CI for any build that does not need lifecycle scripts, and review newly-introduced postinstall scripts in PRs
6. Hunt for `~/.cache/._<scope>_init/`, `tmpdir/._<scope>_init.js`, and `T_IN_ONE_NO_TELEMETRY` environment variables on developer endpoints - these are documented IoCs from Microsoft Defender

## Check your own dependencies

- Check a package-lock.json against this incident: https://dependencywatch.io/check/package-lock-json

The scan runs entirely in the browser; lockfile contents are never uploaded.

## References

- [Malicious npm packages abuse dependency confusion to profile developer environments](https://www.microsoft.com/en-us/security/blog/2026/05/29/33-malicious-npm-packages-abuse-dependency-confusion-profile-developer-environments/) - Microsoft Threat Intelligence

---

Canonical page: https://dependencywatch.io/incident/npm-2026-05-28-moika-dependency-confusion
Markdown version: https://dependencywatch.io/incident/npm-2026-05-28-moika-dependency-confusion.md
Site index for agents: https://dependencywatch.io/llms.txt
DependencyWatch.io is operated by Precursor Security (https://precursorsecurity.com).
