`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.
- Threat actor
- jsonspack DPRK cluster
- Detected by
- CIRCL / Vulnerability-Lookup · Panther (historical attribution)
- Also known as
- jsonspack wave 2 · chai-as-* June 2026 restart · chai-as-assured / chai-as-persisted cluster
- Ecosystems
- npm
- Packages tracked
- 2
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.8published bydiazavasvu195. - 2026-06-26 17:02:41 UTC —
chai-as-assured@7.1.2published as a clean fork preserving the legitimatechai-as-promisedauthor metadata (Domenic Denicola). - 2026-06-27 01:41:12 UTC —
chai-as-persisted@4.2.8published bydiazavasvu195. - 2026-06-27 02:27:14 UTC —
chai-as-persisted@6.1.9published (the high version jump from4.xto6.xmakes the package look more mature than 46 minutes old). - 2026-06-27 — CIRCL / vulnerability-lookup publishes
MAL-2026-6544flagging bothchai-as-persistedversions as deliberate install-time RCE droppers. - 2026-06-28 17:17:42 UTC —
chai-as-assured@6.0.4published bymarkheys3939, this time with thehello@jsonspack.comauthor email,https://jsonspack.com/issuesbugs.url, andsmoke:pino/smoke:filescripts that mirror thechai-as-persistedjsonspack template. - As of 2026-06-29 — all four versions remain live on npm; no
0.0.1-securityholder has replacedlateston either package.
Affected packages (2)
- npm
chai-as-assured7.1.26.0.4 - npm
chai-as-persisted4.2.86.1.9
Impact
- Install-time arbitrary code execution: a
postinstallscript spawns a detached Node child that fetches attacker JavaScript fromipregionchecker.organd evaluates it vianew Function.constructor('require', response)— full Node module access on the installer's machine, persisting afternpm installreturns viachild.unref() --ignore-scriptsis the only flag that prevents detonation — the malicious code never runs fromimport/requireof 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.comauthor contact andchai-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
- 1Remove every reference to
chai-as-persistedfrompackage.json/ lockfiles / CI image layers — the live npm record still serves both4.2.8and6.1.9at the time of this advisory; no0.0.1-securityholder has been published yet - 2Treat any host that ran
npm installagainst a manifest pinningchai-as-persistedas 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 - 3Block
ipregionchecker.org(the C2 endpoint) at egress; hunt firewall and DNS logs for outbound HTTP/HTTPS to this domain since 2026-06-27 - 4Use the legitimate
chai-as-promisedpackage; verify the name letter-by-letter —chai-as-promised, notchai-as-persisted - 5Scan internal Artifactory / Nexus / Verdaccio mirrors for cached tarballs of
chai-as-persistedand purge them — public npm yank does not flush private caches - 6Hunt for other
chai-as-*packages withhello@jsonspack.cominpackage.jsonbugs.url(e.g.https://jsonspack.com/issues) — Panther previously confirmedchai-as-adapter,chai-beta,chai-str,chai-as-hooked,chai-as-redeployed,chai-as-encryptedand other siblings in this same campaign cluster
References
- CIRCL / Vulnerability-LookupMAL-2026-6544 — Malicious code in chai-as-persisted (npm)vulnerability.circl.lu
- npmchai-as-persisted on npmnpmjs.com
- Pantherjsonspack: Multi-Tenant Node.js RAT — DPRK Supply Chain Campaignpanther.com
- PantherInside DPRK's npm malware factory: 108 packages, 261 versions, and a 31-day campaign wavepanther.com