character-ai-sdk@1.0.0
Malicious code in character-ai-sdk (npm)
Analysis
The package ships four heavily obfuscated JavaScript bundles (cache-warm.mjs, cache-sweep.mjs, build-cache.mjs, workspaces.js — 200-300KB each, _0x identifiers, base64+XOR string tables, large blocks of dead arithmetic predicates) alongside an otherwise documented, typed SDK surface. Obfuscated code runs on ordinary use of the package: personas.mjs imports cssVarMap from cache-warm.mjs and calls it from getPersona(); cssVarMap walks up to eight parent directories reading package.json to locate the enclosing project root, then spawns `process.execPath build-cache.mjs` with detached:true, stdio:'ignore', windowsHide:true and a randomised temp path in the environment, and unref()s it — a hidden process that keeps running after the calling application exits. build-cache.mjs writes executable files (chmod 0755) into directories taken from the caller's PATH and into dependency directories, drops a launcher file in the project root, and spawns git and npm with detached:true. The package also ships prebuilt native addons in native/{linux,darwin,win32}/{x64,arm64}/cache-probe.node compiled from the node-vm-detect native host/VM detection project, which no documentation mentions. The hidden bundles contain no network module imports and no cleartext URLs; the decoded string tables hold filesystem and environment-name fragments (e.g. "scope/manifest/breakpoint….json", "_v10"). No NPM_TOKEN, .npmrc or GitHub token references are present in the package.
- analyzed by
- Leitwacht
- first seen
- Oct 31, 2026, 02:22 PM
- analyzed
- Oct 31, 2026, 02:24 PM
Related advisories
- agent-bypass@2.28.0
- charape@1.0.1
- charape@1.0.2
- ts-ankle@1.1.0
- zenith-utils@12.0.14
- hydration-vli-ui@1.0.0
- dim-hydration-ui@1.0.0
- @wizloft/harness-context@0.1.1-alpha.3
Independently detected by the Leitwacht supply-chain probe. IOCs are defanged. Published CC0. Think this is a mistake? See the dispute policy.