# `chai-as-persisted` + `chai-as-assured` - jsonspack DPRK campaign restarts with chai-as-* typosquat install-time RCE dropper

> On 2026-06-26 → 2026-06-28 the same DPRK-linked operator behind the March *jsonspack* npm campaign restarted with `chai-as-persisted` and `chai-as-assured` - typosquats of `chai-as-promised` that ship install-time RCE droppers. Four versions across the two packages were published with the same `hello@jsonspack.com` author bug URL, fetching attacker JavaScript from `ipregionchecker.org` via `new Function.constructor` on every `npm install`.

- Published: 2026-06-27
- Last updated: 2026-07-21
- Severity: high
- Kind: Typosquat - A package that never had a legitimate version, named to be mistaken for a real one - a misspelling, a lookalike scope, or an impersonated vendor SDK.
- Ecosystems: npm
- Scope: 6 packages, 15 compromised versions
- Tags: typosquat, credential-theft, crypto-wallet-drain, infostealer, obfuscation
- Threat actor: jsonspack DPRK cluster
- Also known as: jsonspack wave 2, chai-as-* June 2026 restart, chai-as-assured / chai-as-persisted cluster, chai-as-const / chai-as-thread July 2026 continuation, chai-as-reddit / chai-leaf July 2026 continuation
- Detected by: CIRCL / Vulnerability-Lookup, Panther (historical attribution), GitHub Advisory Database, npm Security
- Incident ID: npm-2026-06-27-chai-as-persisted-jsonspack

## Affected packages (6)

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

| Package | Ecosystem | Compromised versions |
|---|---|---|
| [chai-as-assured](https://dependencywatch.io/package/npm/chai-as-assured) | npm | 7.1.2, 6.0.4 |
| [chai-as-const](https://dependencywatch.io/package/npm/chai-as-const) | npm | 1.4.5, 1.4.6, 1.4.7 |
| [chai-as-persisted](https://dependencywatch.io/package/npm/chai-as-persisted) | npm | 4.2.8, 6.1.9 |
| [chai-as-reddit](https://dependencywatch.io/package/npm/chai-as-reddit) | npm | 7.0.2, 7.0.3, 7.0.4 |
| [chai-as-thread](https://dependencywatch.io/package/npm/chai-as-thread) | npm | 7.0.8 |
| [chai-leaf](https://dependencywatch.io/package/npm/chai-leaf) | npm | 1.4.5, 1.4.6, 1.4.7, 1.4.8 |

## What happened

On 2026-06-27 between 01:41 UTC and 02:27 UTC, a previously-known DPRK-linked operator published two versions of `chai-as-persisted` to npm: `4.2.8` (created 01:41:12 UTC) and `6.1.9` (created 02:27:14 UTC). On 2026-06-26 17:02 UTC the same operator first staged `chai-as-assured@7.1.2` - a clean fork of the legitimate `chai-as-promised` metadata (preserving Domenic Denicola as author) to gauge surface-level detection - then on 2026-06-28 17:17 UTC published the malicious `chai-as-assured@6.0.4` with the same `hello@jsonspack.com` author contact, the `https://jsonspack.com/issues` `bugs.url`, the same `smoke:pino` / `smoke:file` script shell, and the same `axios` + `parse-json` + `request` + `sqlite3` dependency triad. The maintainer for `chai-as-assured` (`markheys3939` / `markheys.eth@outlook.com`) is distinct from `chai-as-persisted` (`diazavasvu195`), matching the *jsonspack* tradecraft of rotating outlook.com publisher accounts while the `package.json` author email (`hello@jsonspack.com`) and bug URL stay constant across the cluster. All four versions are typosquats of the widely-used `chai-as-promised` test-assertion library and are flagged by CIRCL / vulnerability-lookup (`MAL-2026-6544` for `chai-as-persisted`). The package description ("This library/document describes the management of vulnerabilities for the project and all modules within the organization") and keywords (`fast`, `logger`, `stream`, `json`) are deliberately misleading - the shipped code masquerades as a Pino-style logger middleware to defeat surface-level review.

## Install-time RCE chain

The `package.json` declares `"postinstall": "npm run smoke:pino"`, where `smoke:pino` resolves to `node ./index.js`. `index.js` spawns a detached `node lib/initializeCaller.js` child via `child_process` and immediately `child.unref()`s it so execution survives `npm install` returning. `initializeCaller.js` hides the C2 URL inside base64 strings stored on a fabricated local `process.env` object using bait keys `DEV_API_KEY`, `DEV_SECRET_KEY`, `DEV_SECRET_VALUE` - defeating trivial string scanners that grep for the URL or for `atob`.

At run time it `atob()`-decodes the URL to `https://www.ipregionchecker.org/api/ip-check-encrypted/3aeb34a37`, POSTs to it via `axios` (declared as a dependency alongside `parse-json`), and passes the response body to `new Function.constructor("require", response)` - invoking it with the live `require` binding so the second-stage payload has full Node module access on the installer's machine.

## Continuation of the jsonspack DPRK campaign

Panther first documented the *jsonspack* campaign on 2026-04-03 as 27 confirmed malicious npm packages published by eight distinct email accounts between 2026-03-18 and 2026-03-31, all sharing `hello@jsonspack[.]com` as the `package.json` author email. Attribution to a DPRK cluster overlapping Lazarus / Famous Chollima was driven by independent confirmation from the kmsec.uk DPRK npm threat-intelligence feed, which independently identified 24 of the 27 packages as part of a broader 163-package operation. `chai-as-persisted` re-uses the same author contact (`hello@jsonspack.com`, with `bugs.url` set to `https://jsonspack.com/issues`), the same `chai-as-*` typosquat naming convention, and the same Pino-impersonation masquerade - strong evidence the same operator has resumed publication three months after the original wave subsided.

The `npm install`-time exfiltration pattern, the use of `Function.constructor` for staged second-stage execution, and the deliberate string obfuscation are all consistent with the loader architecture Panther reverse-engineered in the original jsonspack cluster. The motivation in that cluster was crypto-wallet theft and credential exfiltration via a 40-wallet browser-extension targeting list, Brave browser emphasis, and 1-second-poll clipboard interception - the financial-targeting priorities consistent with DPRK operations.

## Disclosure timeline

- **2026-06-27 01:41:12 UTC** - `chai-as-persisted@4.2.8` published by `diazavasvu195`.
- **2026-06-26 17:02:41 UTC** - `chai-as-assured@7.1.2` published as a clean fork preserving the legitimate `chai-as-promised` author metadata (`Domenic Denicola`).
- **2026-06-27 01:41:12 UTC** - `chai-as-persisted@4.2.8` published by `diazavasvu195`.
- **2026-06-27 02:27:14 UTC** - `chai-as-persisted@6.1.9` published (the high version jump from `4.x` to `6.x` makes the package look more mature than 46 minutes old).
- **2026-06-27** - CIRCL / vulnerability-lookup publishes `MAL-2026-6544` flagging both `chai-as-persisted` versions as deliberate install-time RCE droppers.
- **2026-06-28 17:17:42 UTC** - `chai-as-assured@6.0.4` published by `markheys3939`, this time with the `hello@jsonspack.com` author email, `https://jsonspack.com/issues` `bugs.url`, and `smoke:pino` / `smoke:file` scripts that mirror the `chai-as-persisted` jsonspack template.
- **As of 2026-06-29** - all four versions remain live on npm; no `0.0.1-security` holder has replaced `latest` on either package.
- **2026-07-07** - jsonspack operator publishes `chai-as-const@1.4.5` (09:20 UTC) and `chai-as-thread@7.0.8` (18:05 UTC), continuing the `chai-as-*` typosquat naming convention.
- **2026-07-16** - `chai-as-const@1.4.6` (20:24 UTC) and `1.4.7` (20:33 UTC) published, followed by npm-Security take-down: `chai-as-thread` retired 2026-07-16 15:20 UTC (GHSA-pjgc-4vf2-4cj7), `chai-as-const` retired 2026-07-16 21:23 UTC (GHSA-c2cc-6c6f-8qrp). Both now resolve to `0.0.1-security` holding tarballs.
- **2026-07-18 → 2026-07-21** - jsonspack operator continues with three new `chai-*` typosquats: `chai-as-reddit@7.0.2` (2026-07-18 04:47 UTC), `chai-as-reddit@7.0.3` (2026-07-18 10:04 UTC), `chai-as-reddit@7.0.4` (2026-07-21 00:24 UTC), and `chai-leaf@1.4.5` → `1.4.8` (four versions published across 2026-07-19 → 2026-07-20). Both packages were npm-Security-retired 2026-07-21: `chai-as-reddit` at 00:39 UTC (GHSA-vc32-h28h-pmhm) and `chai-leaf` (GHSA-m3c7-2j38-rjh7). The `chai-leaf` name breaks the exact `chai-as-*` convention but fits the broader `chai-*` cover pattern Panther documented in the original jsonspack cluster (`chai-beta`, `chai-str`).

## Impact

- Install-time arbitrary code execution: a `postinstall` script spawns a detached Node child that fetches attacker JavaScript from `ipregionchecker.org` and evaluates it via `new Function.constructor('require', response)` - full Node module access on the installer's machine, persisting after `npm install` returns via `child.unref()`
- `--ignore-scripts` is the only flag that prevents detonation - the malicious code never runs from `import`/`require` of the package
- Continuation of the *jsonspack* DPRK supply-chain campaign Panther first documented in March–April 2026 (27 confirmed packages from 2026-03-18 to 2026-03-31, attributed to a DPRK cluster overlapping Lazarus / Famous Chollima); the same `hello@jsonspack.com` author contact and `chai-as-*` typosquat naming pattern resurface here three months later
- Likely follow-on credential and crypto-wallet theft - the jsonspack loader architecture has historically dropped browser-extension wallet stealers, clipboard hijackers, and `~/.aws/credentials` / `~/.ssh/*` exfiltrators consistent with DPRK financial-targeting priorities

## What to do

1. Remove every reference to `chai-as-persisted` from `package.json` / lockfiles / CI image layers - the live npm record still serves both `4.2.8` and `6.1.9` at the time of this advisory; no `0.0.1-security` holder has been published yet
2. Treat any host that ran `npm install` against a manifest pinning `chai-as-persisted` as fully compromised: rotate all credentials, browser session cookies, SSH keys, npm tokens, GitHub tokens, AWS / GCP / Azure CLI tokens, and crypto-wallet seed phrases from a separate clean device
3. Block `ipregionchecker.org` (the C2 endpoint) at egress; hunt firewall and DNS logs for outbound HTTP/HTTPS to this domain since 2026-06-27
4. Use the *legitimate* `chai-as-promised` package; verify the name letter-by-letter - `chai-as-promised`, not `chai-as-persisted`
5. Scan internal Artifactory / Nexus / Verdaccio mirrors for cached tarballs of `chai-as-persisted` and purge them - public npm yank does not flush private caches
6. Hunt for other `chai-as-*` packages with `hello@jsonspack.com` in `package.json` `bugs.url` (e.g. `https://jsonspack.com/issues`) - Panther previously confirmed `chai-as-adapter`, `chai-beta`, `chai-str`, `chai-as-hooked`, `chai-as-redeployed`, `chai-as-encrypted` and other siblings in this same campaign cluster

## 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

- [MAL-2026-6544 - Malicious code in chai-as-persisted (npm)](https://vulnerability.circl.lu/vuln/mal-2026-6544) - CIRCL / Vulnerability-Lookup
- [chai-as-persisted on npm](https://www.npmjs.com/package/chai-as-persisted) - npm
- [jsonspack: Multi-Tenant Node.js RAT - DPRK Supply Chain Campaign](https://panther.com/blog/jsonspack-multi-tenant-node.js-rat-%E2%80%94-dprk-supply-chain-campaign) - Panther
- [Inside DPRK's npm malware factory: 108 packages, 261 versions, and a 31-day campaign wave](https://panther.com/blog/inside-dprk%E2%80%99s-npm-malware-factory-108-packages-261-versions-and-a-31-day-campaign-wave) - Panther
- [GHSA-c2cc-6c6f-8qrp - chai-as-const malware advisory](https://github.com/advisories/GHSA-c2cc-6c6f-8qrp) - GitHub
- [GHSA-pjgc-4vf2-4cj7 - chai-as-thread malware advisory](https://github.com/advisories/GHSA-pjgc-4vf2-4cj7) - GitHub
- [GHSA-vc32-h28h-pmhm - chai-as-reddit malware advisory](https://github.com/advisories/GHSA-vc32-h28h-pmhm) - GitHub
- [GHSA-m3c7-2j38-rjh7 - chai-leaf malware advisory](https://github.com/advisories/GHSA-m3c7-2j38-rjh7) - GitHub

---

Canonical page: https://dependencywatch.io/incident/npm-2026-06-27-chai-as-persisted-jsonspack
Markdown version: https://dependencywatch.io/incident/npm-2026-06-27-chai-as-persisted-jsonspack.md
Site index for agents: https://dependencywatch.io/llms.txt
DependencyWatch.io is operated by Precursor Security (https://precursorsecurity.com).
