Overview
On May 26, 2026, a user calling themselves "Maxwell" posted in the #jobs channel of Elastic's public community Slack workspace, claiming to be upgrading an e-commerce platform to "a modern, scalable architecture using Next.js (v14), NestJS, PostgreSQL, and Auth.js" and looking for an experienced developer to help. Interested developers were moved into direct messages and asked to complete a take-home coding assessment -- a familiar Contagious Interview playbook that has been running since at least December 2022.
What was not familiar was how the payload was hidden. Elastic Security Labs, which discovered the campaign after the actor targeted its own Slack community, found that the malicious code was split into Base64-encoded fragments and stashed inside HTML comments across every SVG "flag" image (AE.svg, AF.svg, and so on) bundled into the trojanized repository's assets directory. A helper script reassembled the fragments in alphabetical order and eval()'d the result on every server start. Elastic states this specific infection chain "has not been previously documented," and that none of the trojanized archives were flagged by any antivirus vendor at the time of publication.
Elastic tracks this activity cluster as REF9403 and assesses the payload as OTTERCOOKIE-aligned. This campaign is seeing active exploitation, nation-state (DPRK) attribution, and 13 associated indicators of compromise (nine file hashes, four C2 domains).
Threat Actor Profile
Contagious Interview (also referenced in industry reporting alongside the malware families BEAVERTAIL and OTTERCOOKIE) is a DPRK-aligned social engineering and malware operation that has run continuously since at least late 2022, with the goal of compromising individual software developers to steal credentials, source code, and cryptocurrency, and to establish footholds that can cascade into broader supply chain compromise. Microsoft documented the campaign's fake-interview tradecraft in a March 11, 2026 writeup, and NTT Security first disclosed OTTERCOOKIE in December 2024.
Elastic's assessment is that the group's toolset has been converging: historically, BEAVERTAIL served as a first-stage stealer/downloader while OTTERCOOKIE operated as a later-stage, C2-driven infostealer and RAT. In the samples analyzed for this campaign, Elastic observed a consolidated, all-in-one package -- a Socket.IO-based RAT, clipboard stealer, and combined credential/wallet/file stealer -- with no separate Python stage, leading Elastic to lean toward the OTTERCOOKIE naming convention while noting the boundary between the two families "is no longer clear."
The operation also shares infrastructure and code-level overlap with a separate but related DPRK campaign distributing malicious npm packages masquerading as Rollup polyfill tooling, identified by JFrog Security research, indicating the actor is running multiple propagation vectors in parallel: open-source package registries and direct social-engineering delivery through developer-facing forums.
Victimology: Individual software developers and open-source contributors, reached through public developer communities (Slack workspaces, freelance job boards, and similar forums) rather than any single named organization. Elastic found no evidence the lure was targeted specifically at Elastic's users -- any developer-facing open forum is a potential watering hole.

Attack Chain
Stage 1 -- Social Engineering and Lure Delivery
The actor posts a fabricated, plausible-sounding freelance or contract developer job listing in a public forum (in this case, a vendor's community Slack #jobs channel), then moves promising conversations into direct messages. The victim is asked to complete a "coding challenge" or take-home assignment as a condition of the job offer -- a long-standing Contagious Interview tactic.
Stage 2 -- Trojanized Repository Delivery
The victim receives a link to, or archive of, a repository that is a copy of a legitimate open-source project (in this case, the GoCart Next.js e-commerce template by GreatStackDev). The actor has inserted small snippets of malicious code at scattered points in the codebase and used benign-sounding variable names to blend in. Observed archive names distributed in this wave include next-ecommerce-private-main.zip, shopping-platform-main.zip, ecommerce-platform.zip, ecommerce-platform-main.zip, shopping-platform.rar, shop-main.zip, and ecommerce-main.zip.
Stage 3 -- Steganographic Payload Storage
The actual malicious payload never appears in the JavaScript source as a readable blob. Instead it is split into Base64 fragments and embedded inside HTML comments within every SVG country-flag image under the project's assets/flags directory. Each flag file otherwise renders normally as a country flag image, so a visual or cursory code review would not surface anything unusual.
Stage 4 -- Reassembly and Execution
A bundled file, serverValidation.js, reads every .svg file in the flags directory in alphabetical order, extracts the HTML comment from each, concatenates the fragments, and returns the joined string. A second function, Check(), performs custom Base64 decoding on the reassembled data, and the result is passed directly to eval() -- deliberately avoiding Buffer.from or atob() calls that simple static or behavioral rules might flag. The project's package.json wires this into both npm run dev and npm start, so server/index.js invokes the reassembly-and-eval routine on every single server boot, guaranteeing repeated execution as the developer works on the "assignment."
Stage 5 -- Payload Execution: Four Concurrent Modules
Once decoded and evaluated, four modules launch:
- Browser credential and crypto-wallet stealer. Sets its process title to
npm-cacheto blend into Task Manager/process listings. Enumerates Chrome, Edge, Brave, Opera, and "LT Browser" profile paths across Windows, macOS, and Linux, exfiltrating saved logins, autofill data, and 25 named cryptocurrency wallet browser-extension datastores (MetaMask, Phantom, Trust Wallet, and others) via multipart HTTP POST toldb.rightwidth[.]dev/uploadand/cldbs, using the user agentaxios/1.18.1. On macOS, the system keychain (~/Library/Keychains/login.keychain-db) is also collected. - File stealer. Recursively sweeps mounted drives (enumerated via
wmic logicaldisk get nameon Windows) or home directories (macOS/Linux) for files matching a broad glob list (.env*,.doc(x),.pdf,.pem,.json,.ts,.js, shell history files, and more), plus anything under credential-store paths such as.aws,.azure,.ssh. Matches are uploaded unencrypted via POST toupload.rightwidth[.]dev/upload. The exclusion list is notably curated to skip AI coding-assistant directories (.claude,.cursor,.gemini,.windsurf,.pearai) -- not to protect them, but to reduce exfiltration noise and focus signal on higher-value targets. - Socket.IO-based RAT. Establishes a persistent Socket.IO channel over HTTPS to
controller.rightwidth[.]dev, enforcing single-instance execution via a PID lock file (observed atC:\Users\<user>\.npm\vhost.ctl). Performs VM/sandbox detection (checking forvmware,virtualbox,qemu, and similar strings viawmic,system_profiler, or/proc/cpuinfodepending on OS) and tags -- but does not block -- suspected sandbox hosts in its C2 check-in, likely to help the operator prioritize real victims. Registers new victims via/api/service/process/<uid>and reports implant health via/api/service/makelog. Operator-issuedcommandevents are executed viachild_process.exec(), giving interactive remote shell access. - Clipboard stealer and Windows dropper. Polls the clipboard every 500ms (
pbpasteon macOS, a freshGet-ClipboardPowerShell process on Windows) and exfiltrates changes torightwidth[.]dev/api/service/makelog/. On Windows only, this module also downloads three additional binaries viacurlfromfile.rightwidth[.]dev, disguised as.txtfiles (hostService.txt,printSvc.txt,dhcpSvc.txt) and renamed to.exebefore execution. Elastic was unable to retrieve these second-stage binaries because the C2 was unavailable at analysis time, so their exact capability remains unconfirmed.
Defense Evasion
The JavaScript payload is packed with obfuscator.io, using string-array extraction with index-based lookups, a self-rotating anti-tampering array, and infinite-loop toolmarks (while (!![])) -- all standard commodity JS obfuscation, but combined here with the SVG steganography to defeat both static file-content scanning and casual code review.
Timeline
| Date | Event |
|---|---|
| December 2022 | Contagious Interview campaign family first begins operating (per prior public reporting). |
| September 2024 | OTTERCOOKIE malware family first emerges (per Hacker News reporting on OTTERCOOKIE v4). |
| December 2024 | NTT Security first publicly documents OTTERCOOKIE. |
| March 11, 2026 | Microsoft publishes writeup on Contagious Interview fake developer job interview tradecraft. |
| May 26, 2026 | "Maxwell" posts fake e-commerce developer job listing in Elastic's community Slack #jobs channel; victims moved to DMs and given a trojanized coding-challenge repository. |
| July 2026 (undated, pre-publication) | JFrog Security links related infrastructure/API endpoint patterns to a separate DPRK npm "Rollup polyfill" masquerading campaign. |
| July 17-18, 2026 | Elastic Security Labs publishes full technical findings (tracked as REF9403); The Hacker News and other outlets syndicate coverage. |
| July 18, 2026 | Campaign flagged High risk in internal Morning Threat Intelligence Brief with 13 associated IOCs. |
Detection Guidance
Network Layer
- C2 domain resolution/traffic: Alert on any DNS resolution or HTTP(S)/proxy traffic to
rightwidth[.]devor its subdomainsldb.rightwidth[.]dev,upload.rightwidth[.]dev,controller.rightwidth[.]dev, andfile.rightwidth[.]dev. SeeDRAFT_PXY-NEW09-RUN.yml. - Known API endpoint paths: Independent of domain, watch for outbound requests to the path patterns
/api/service/makelog,/api/service/process/<uid>,/cldbs, and/upload-- these endpoint names have also been linked by JFrog to the related Rollup-polyfill npm campaign, suggesting they may recur across future infrastructure changes. - Ingress tool transfer via curl: Flag
curlprocess invocations that reference the rightwidth[.]dev domain family, particularly where the retrieved file has a.txtextension but is subsequently renamed and executed as.exe. SeeDRAFT_EDR-NEW14-RUN.yml.
Process / Endpoint Layer
- Process masquerading: Alert on processes with title/name
npm-cachethat do not correspond to an actual npm cache-verification workflow, particularly when observed alongside outbound connections to non-npm-registry infrastructure. - Known trojanized archive hashes: Match file-write/download telemetry against the nine SHA-256 hashes for the identified trojanized repository archives. See
DRAFT_EDR-NEW13-RUN.yml. Treat this as perishable coverage -- zero AV vendors detected these samples at time of publication, and file/archive names are generic and likely to be rotated in future waves. - Node.js reassembly-and-eval pattern: Where source-level or runtime JS instrumentation is available, flag Node.js server processes that read and
eval()content dynamically reconstructed from image file contents/comments -- an unusual and high-signal behavior for a production or development server process. - Suspicious WMI/system enumeration paired with Node.js:
wmic logicaldisk get name,wmic computersystem get model,manufacturer, and repeatedGet-ClipboardPowerShell invocations (every ~500ms) spawned from or alongside a Node.js parent process are anomalous and worth correlating. - PID lock file artifact: The RAT module's single-instance lock file was observed at
%USERPROFILE%\.npm\vhost.ctl-- an atypical path for legitimate npm operations and worth a targeted file-creation watch.
Identity / Credential Layer
- Browser credential store access from Node.js processes: Alert on Node.js or related development-tooling processes reading Chrome/Edge/Brave/Opera
Login Data,Web Data, orLocal Extension Settingsfiles outside of expected browser-automation/testing workflows. - Cryptocurrency wallet extension data access: Monitor for reads of the LevelDB stores associated with the 25 targeted wallet extension IDs (MetaMask, Phantom, Trust Wallet, Rabby, and others) from non-browser processes.
- macOS keychain access: Flag non-standard process access to
~/Library/Keychains/login.keychain-db.
Indicators of Compromise
Network
| Type | Indicator | Notes |
|---|---|---|
| Domain | rightwidth[.]dev | Root C2 domain; clipboard exfil via /api/service/makelog/ |
| Domain | ldb.rightwidth[.]dev | Browser credential + crypto wallet stealer C2 (/upload, /cldbs) |
| Domain | upload.rightwidth[.]dev | File-stealer exfiltration endpoint (/upload) |
| Domain | controller.rightwidth[.]dev | Socket.IO RAT registration/beacon (/api/service/process/<uid>, /api/service/makelog) |
| Domain | file.rightwidth[.]dev | Windows second-stage binary staging host |
| IPv4 | 195.26.248[.]212 | OTTERCOOKIE C2 server (per Elastic) |
| IPv4 | 188.40.64[.]61 | OTTERCOOKIE C2 server (per Elastic) |
File Hashes (SHA-256)
| Hash | Associated File |
|---|---|
3e6360f83a95540aa2176d279ca4694513afb1e5116a7ffe591c6b5bcf3b9c3c | next-ecommerce-private-main.zip |
4e7639045b4a64de60bfb6312951a5c3dffbd3fb04b84837663242ed27f09864 | shopping-platform-main.zip |
54bf36910d81ab516037cb3d69d7c85190f90aa0da9e58617799c1fc738dc5a9 | ecommerce-platform.zip |
8e571d58794b9b44ae53c2c67bedef72c500e8adbb80aab7a5c263adcba55b1e | ecommerce-main.zip |
96357529d17c4690826d5d4c74deac51743a5388733b3f04004d898f0635ef20 | shop-main.zip |
9df01d242ef46adfedf8c35cb7cc67b1d27d7dc4a1ce74ab32e984090d579886 | ecommerce-platform-main.zip |
c5aed4c063d4970a03250778da8041da9e0c83d8f22d2f1994da0ad72567ebd9 | shopping-platform.rar |
cc97517f80f567977300450de11e9a0be53f52657525a20b1091c99fe9e45730 | shopping-platform.rar (second sample) |
fb94b2caee2c40635448a98ba0118421e19a400e74ccff73315f8fa42351f53f | shop-main.zip (second sample) |
Host Artifacts
| Type | Value |
|---|---|
| Process title masquerade | npm-cache (credential/wallet stealer module) |
| PID lock file | %USERPROFILE%\.npm\vhost.ctl |
| Second-stage payload (unconfirmed capability) | hostService.txt -> hostService.exe |
| Second-stage payload (unconfirmed capability) | printSvc.txt -> printSvc.exe |
| Second-stage payload (unconfirmed capability) | dhcpSvc.txt -> dhcpSvc.exe |
| Targeted repository template | GoCart (Next.js e-commerce template, GreatStackDev) |
MITRE ATT&CK Mapping
| Technique ID | Technique Name | Usage |
|---|---|---|
| T1566.001 | Phishing: Spearphishing Attachment | Trojanized repository delivered as a "coding challenge" via DM |
| T1204.002 | User Execution: Malicious File | Victim runs npm run dev/npm start, triggering payload execution |
| T1001.002 | Data Obfuscation: Steganography | Payload fragments hidden in HTML comments inside SVG flag images |
| T1027 | Obfuscated Files or Information | obfuscator.io JS packing; custom Base64 Check() decoder instead of atob()/Buffer.from |
| T1082 | System Information Discovery | wmic logicaldisk get name, wmic computersystem get model,manufacturer, VM/sandbox detection |
| T1083 | File and Directory Discovery | Recursive file-stealer glob sweep across drives/home directories |
| T1555 | Credentials from Password Stores | Browser Login Data/Web Data and macOS keychain access |
| T1005 | Data from Local System | File stealer collection of documents, configs, source code |
| T1115 | Clipboard Data | 500ms clipboard polling module |
| T1071.001 | Application Layer Protocol: Web Protocols | Socket.IO RAT and HTTP(S) POST-based exfil channels |
| T1105 | Ingress Tool Transfer | curl-based download of second-stage Windows binaries |
| T1036.008 | Masquerading: Masquerade File Type | .txt-to-.exe rename of downloaded binaries |
| T1041 | Exfiltration Over C2 Channel | Credential, wallet, file, and clipboard data sent to rightwidth[.]dev endpoints |
Key Takeaways
Steganography moves from novelty to operational tradecraft. Hiding payload fragments inside HTML comments in ordinary-looking SVG image assets is a meaningfully different evasion technique from prior Contagious Interview waves, and one that neither static file scanning nor a quick visual code review is well-suited to catch. Security teams that rely primarily on "does this file look like an image" checks should treat SVG (and other markup-based image formats that permit comments or metadata) as a viable code-smuggling vector going forward.
The developer supply chain remains the softest target. This campaign did not need a zero-day or a novel exploit -- it needed one developer to run npm start on a plausible-looking take-home assignment. Elastic's own framing is worth repeating directly: a single compromised developer "can provide the initial access needed to enable far-reaching supply chain attacks against downstream organizations."
Zero AV detection is the norm, not the exception, for these lures. None of the trojanized archives identified in this wave were flagged by any antivirus vendor. Detection strategy for this actor class has to lean on behavioral and network indicators (unusual eval() patterns, C2 domain/endpoint matching, curl-then-rename execution chains) rather than signature or reputation-based file scanning alone.
Infrastructure and tooling convergence across DPRK campaigns. The overlap in API endpoint naming between this campaign and the separate Rollup-polyfill npm masquerading campaign, and the general blurring of the line between BEAVERTAIL and OTTERCOOKIE, suggests shared development resources or personnel across what look like independent campaigns. Detections built around durable behavioral patterns (rather than any single campaign's specific domains or hashes) are likely to have a longer useful life against this actor.
References
- Stepanic, D. (2026, July 18). New North Korean campaign uses fake coding interviews to steal developer credentials. Elastic Security Labs. https://www.elastic.co/security-labs/contagious-interview-malware-svg-steganography
- Lakshmanan, R. (2026, July 17). Fake Coding Tests Deliver OtterCookie-Aligned Malware Hidden in SVG Flag Images. The Hacker News. https://thehackernews.com/2026/07/north-korea-linked-hackers-hide.html
- Microsoft Security. (2026, March 11). Contagious Interview malware delivered through fake developer job interviews. https://www.microsoft.com/en-us/security/blog/2026/03/11/contagious-interview-malware-delivered-through-fake-developer-job-interviews/
- NTT Security. (2024, December). OTTERCOOKIE: Contagious Interview malware analysis. https://jp.security.ntt/insights_resources/tech_blog/en-contagious-interview-ottercookie/
- JFrog Security Research. (2026). Rollup polyfill masquerading infrastructure. https://research.jfrog.com/post/rollup-polyfill-masquerading/
- The Hacker News. (2025, May). OtterCookie v4 Adds VM Detection and Enhanced Data Theft Capabilities. https://thehackernews.com/2025/05/ottercookie-v4-adds-vm-detection-and.html
- MITRE ATT&CK. (2024). Data Obfuscation: Steganography (T1001.002). https://attack.mitre.org/techniques/T1001/002/
