{"rules_version":"2026.09.21c","generated_at":"2026-09-22","page":"https://lazaretto.dev/benchmark","how_to_read":"Each number carries the corpus it was measured on, and we chose every corpus. None of these is a random sample of the registry, and none of them is a field measurement. Read each `measures` field before quoting the number next to it. Members name packages, not versions: see `caveats`.","members_identify":"package names, not versions. Each member was scanned at whatever release the registry served on the corpus `measured_at` date, and that release is not recorded here.","recall":{"caught":21,"total":22,"measures":"attack samples detected out of the ones in our corpus. We wrote every sample. Only some were written from published write-ups of specific npm incidents; most are technique families and evasion variants we wrote ourselves, which reconstruct a class of attack rather than any one published incident. Not every sample is an npm package either: the corpus also holds poisoned CI workflows, an agent skill carrying a prompt injection, and loose Python source files. The `composition` field counts which is which, and every sample below carries its own `written` and `target`. It is NOT field recall: nobody can tell you what fraction of live attacks a scanner catches, because nobody has the denominator.","corpus":"Samples written by us and scanned by us. A few follow published incident reports; the rest are attack classes and evasion variants we wrote, and they are not all npm packages.","composition":{"by_how_it_was_written":{"published incident report":3,"technique family we wrote":17,"evasion variant we wrote":2},"by_what_it_is":{"npm package":16,"Python source file":3,"CI workflow":2,"agent skill":1},"note":"Counted from the samples themselves, not written into a sentence."},"missed":[{"name":"payload hidden inside a minified bundle","based_on":"attacker ships the stealer inside a published dist bundle","why":"Minified and bundled files are left out of the source-level rules on purpose. A single dense line of machine-written code produces so many spurious matches on ordinary packages that including it would flag half the registry, and a scanner that flags everything is one people turn off. The trade is real and we take it knowingly: a stealer buried in a published dist bundle can get past this, which is why a report that could not read part of an artifact says it was only partly analyzed instead of returning a confident clear."}],"samples":[{"name":"postinstall dropper","based_on":"ua-parser-js / coa / rc (2021): postinstall fetches and runs a remote binary","written":"published incident report","target":"npm package","labelled":"catch","caught":true},{"name":"ssh + cloud credential stealer","based_on":"typosquat crypto/credential stealers: read key material, POST to hardcoded host","written":"technique family we wrote","target":"npm package","labelled":"catch","caught":true},{"name":"npm token + env harvest","based_on":"Shai-Hulud (2025): harvest npm/GitHub tokens and env, exfil to attacker endpoint","written":"published incident report","target":"npm package","labelled":"catch","caught":true},{"name":"obfuscated decode-then-eval loader","based_on":"event-stream / flatmap-stream (2018): decrypt a blob at runtime, then execute it","written":"published incident report","target":"npm package","labelled":"catch","caught":true},{"name":"decoded into a variable, then evaluated","based_on":"the same loader with the decode and the eval split by a variable, the first thing an author tries to dodge a one-expression pattern","written":"evasion variant we wrote","target":"npm package","labelled":"catch","caught":true},{"name":"crypto wallet stealer","based_on":"wallet-draining typosquats: read wallet files, exfil","written":"technique family we wrote","target":"npm package","labelled":"catch","caught":true},{"name":"self-updating beacon","based_on":"persistent loaders: periodically pull and execute remote code","written":"technique family we wrote","target":"npm package","labelled":"catch","caught":true},{"name":"payload hidden inside a minified bundle","based_on":"attacker ships the stealer inside a published dist bundle","written":"technique family we wrote","target":"npm package","labelled":"may-miss","caught":false,"note":"Minified and bundled files are left out of the source-level rules on purpose. A single dense line of machine-written code produces so many spurious matches on ordinary packages that including it would flag half the registry, and a scanner that flags everything is one people turn off. The trade is real and we take it knowingly: a stealer buried in a published dist bundle can get past this, which is why a report that could not read part of an artifact says it was only partly analyzed instead of returning a confident clear."},{"name":"DNS-based exfiltration","based_on":"covert channel: encode secrets into DNS lookups (no HTTP sink)","written":"technique family we wrote","target":"npm package","labelled":"may-miss","caught":true,"note":"Secrets carried out inside DNS lookups never touch an HTTP sink, so nothing about the traffic looks like sending data anywhere. This one was written as a case we expected to miss and was later covered; it stays in the corpus labelled the way it was written, because quietly promoting a sample once you pass it is how a benchmark stops meaning anything."},{"name":"reverse shell in a postinstall","based_on":"bash /dev/tcp reverse shell dropped by an install script (common CTF/malware idiom)","written":"technique family we wrote","target":"npm package","labelled":"catch","caught":true},{"name":"Discord-webhook token stealer","based_on":"many 2023-2025 npm token stealers: read npm/env secrets, POST to a Discord webhook (a \"normal\" domain)","written":"technique family we wrote","target":"npm package","labelled":"catch","caught":true},{"name":"clipboard crypto clipper","based_on":"clipper malware: poll the clipboard and swap a copied wallet address for the attacker's","written":"technique family we wrote","target":"npm package","labelled":"catch","caught":true},{"name":"multi-provider env token harvest","based_on":"Shai-Hulud-style worm / token stealers: collect NPM/GitHub/AWS secrets from env and POST them","written":"technique family we wrote","target":"npm package","labelled":"catch","caught":true},{"name":"remote code loader to a domain","based_on":"dropper that fetches a stage-2 payload from a DOMAIN (no hardcoded IP) and execs it","written":"technique family we wrote","target":"Python source file","labelled":"catch","caught":true},{"name":"bin shadows a system command","based_on":"metadata attack: a package whose bin shadows git/npm so a global install hijacks the command","written":"technique family we wrote","target":"npm package","labelled":"catch","caught":true},{"name":"CI workflow secret exfiltration","based_on":"poisoned GitHub Actions workflow that POSTs a build secret to an attacker host","written":"technique family we wrote","target":"CI workflow","labelled":"catch","caught":true},{"name":"Windows LOLBin dropper via postinstall","based_on":"Windows-targeted npm malware: postinstall uses certutil to fetch a remote exe","written":"technique family we wrote","target":"npm package","labelled":"catch","caught":true},{"name":"in-memory shellcode injection","based_on":"loader that allocates executable memory and runs a raw shellcode buffer","written":"technique family we wrote","target":"Python source file","labelled":"catch","caught":true},{"name":"obfuscated dynamic import (anti-analysis)","based_on":"evasion: assemble the module name from fragments so a static scan never sees \"os\"","written":"evasion variant we wrote","target":"Python source file","labelled":"catch","caught":true},{"name":"credential exfil to a throwaway sink","based_on":"reads env/npm secrets and POSTs them to a webhook.site capture URL","written":"technique family we wrote","target":"npm package","labelled":"catch","caught":true},{"name":"CI workflow dropper from a raw IP","based_on":"poisoned GitHub Actions step fetches a payload from a bare IP and pipes it to a shell","written":"technique family we wrote","target":"CI workflow","labelled":"catch","caught":true},{"name":"agent skill exfiltrates via a rendered image","based_on":"prompt-injection in an agent SKILL.md: a markdown image whose URL templates the conversation to an attacker host","written":"technique family we wrote","target":"agent skill","labelled":"catch","caught":true}]},"surveys":[{"id":"popular","title":"Popular npm packages","measures":"packages flagged by our rules out of the whole list, with no indicator feed in play","corpus_chosen_by_us":"The list we publish package pages for, chosen by us for search traffic, not sampled from the registry at random. It is weighted to packages a working developer installs on purpose, which is the population a noisy scanner annoys.","size":154,"flagged":8,"unreadable":6,"disagreed_with_our_label":[{"ref":"figlet","expect":"clear","verdict":"flagged"},{"ref":"jose","expect":"clear","verdict":"flagged"},{"ref":"jsdom","expect":"clear","verdict":"flagged"},{"ref":"mongodb","expect":"clear","verdict":"flagged"},{"ref":"pm2","expect":"clear","verdict":"flagged"},{"ref":"ts-node","expect":"clear","verdict":"flagged"},{"ref":"vite","expect":"clear","verdict":"flagged"},{"ref":"xstate","expect":"clear","verdict":"flagged"}],"rules_version":"2026.09.21c","measured_at":"2026-09-22","members":[{"verdict":"clear","risk":"none","categories":[],"ref":"adm-zip","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"ajv","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"apollo-server","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"archiver","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"argon2","expect":"clear"},{"verdict":"error","risk":"none","categories":[],"note":"fetch failed: unreachable (npm: packument-fetch)","ref":"autoprefixer","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"ava","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"axios","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"babel-core","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"bcrypt","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"bcryptjs","expect":"clear"},{"verdict":"error","risk":"none","categories":[],"note":"fetch failed: too_large (fetch: content-length 11402131)","ref":"better-sqlite3","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"body-parser","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"boxen","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"browserify","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"chai","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"chalk","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"cheerio","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"chokidar","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"classnames","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"commander","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"compression","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"concurrently","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"cors","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"cosmiconfig","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"cross-env","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"cross-spawn","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"crypto-js","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"cypress","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"date-fns","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"dayjs","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"debug","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"deepmerge","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"del","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"dompurify","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"dotenv","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"ejs","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"enquirer","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"esbuild","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"eslint","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"execa","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"express","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"fast-glob","expect":"clear"},{"verdict":"flagged","risk":"high","categories":["prompt_injection"],"ref":"figlet","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"follow-redirects","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"form-data","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"fs-extra","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"glob","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"globby","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"got","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"graphql","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"grunt","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"gulp","expect":"clear"},{"verdict":"error","risk":"none","categories":[],"note":"analysis exceeded the time budget","ref":"handlebars","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"helmet","expect":"clear"},{"verdict":"error","risk":"none","categories":[],"note":"fetch failed: internal (unexpected: other side closed)","ref":"highlight.js","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"http-proxy","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"husky","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"immer","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"immutable","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"inquirer","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"ioredis","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"jest","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"joi","expect":"clear"},{"verdict":"flagged","risk":"high","categories":["credential_access"],"ref":"jose","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"jquery","expect":"clear"},{"verdict":"flagged","risk":"high","categories":["credential_access","obfuscation"],"ref":"jsdom","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"jsonwebtoken","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"kleur","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"knex","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"lint-staged","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"lodash","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"luxon","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"markdown-it","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"marked","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"meow","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"minimatch","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"minimist","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"mobx","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"mocha","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"moment","expect":"clear"},{"verdict":"flagged","risk":"high","categories":["credential_access"],"ref":"mongodb","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"mongoose","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"morgan","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"multer","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"mustache","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"mysql2","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"nanoid","expect":"clear"},{"verdict":"error","risk":"none","categories":[],"note":"fetch failed: too_large (fetch: content-length 41747455)","ref":"next","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"node-cron","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"node-fetch","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"nodemailer","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"nodemon","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"nunjucks","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"nyc","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"ora","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"passport","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"pg","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"picocolors","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"pino","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"playwright","expect":"clear"},{"verdict":"flagged","risk":"high","categories":["obfuscation","persistence"],"ref":"pm2","expect":"clear"},{"verdict":"error","risk":"none","categories":[],"note":"fetch failed: unreachable (npm: packument-fetch)","ref":"postcss","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"prettier","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"prisma","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"prompts","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"pug","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"puppeteer","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"qs","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"ramda","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"react","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"react-dom","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"redis","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"redux","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"request","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"rimraf","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"rollup","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"rxjs","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"sanitize-html","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"sass","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"semver","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"sequelize","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"sharp","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"shelljs","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"sinon","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"socket.io","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"sqlite3","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"superagent","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"supertest","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"svelte","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"tailwindcss","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"tape","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"tar","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"terser","expect":"clear"},{"verdict":"flagged","risk":"high","categories":["prompt_injection"],"ref":"ts-node","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"tsx","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"typeorm","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"typescript","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"underscore","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"undici","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"unzipper","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"uuid","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"validator","expect":"clear"},{"verdict":"flagged","risk":"high","categories":["credential_access","obfuscation"],"ref":"vite","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"vitest","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"vue","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"webpack","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"winston","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"ws","expect":"clear"},{"verdict":"flagged","risk":"high","categories":["credential_access"],"ref":"xstate","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"yargs","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"yup","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"zod","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"zustand","expect":"clear"}]},{"id":"adversarial","title":"Adversarial npm packages","measures":"packages whose result disagreed with the label we wrote down before running them","corpus_chosen_by_us":"Chosen by us because each one legitimately does something our rules look for: reads cloud credentials, posts to a chat webhook, spawns shells, compiles code at run time, or runs an install step that downloads a binary. Every label was written before the run.","size":53,"flagged":4,"unreadable":3,"disagreed_with_our_label":[{"ref":"bcrypt","expect":"flagged","verdict":"clear"},{"ref":"esbuild","expect":"flagged","verdict":"clear"},{"ref":"ethers","expect":"clear","verdict":"flagged"},{"ref":"node-gyp","expect":"clear","verdict":"flagged"},{"ref":"pm2","expect":"clear","verdict":"flagged"},{"ref":"puppeteer","expect":"flagged","verdict":"clear"},{"ref":"serverless","expect":"clear","verdict":"flagged"},{"ref":"sharp","expect":"flagged","verdict":"clear"},{"ref":"sqlite3","expect":"flagged","verdict":"clear"}],"rules_version":"2026.09.21c","measured_at":"2026-09-22","members":[{"verdict":"clear","risk":"none","categories":[],"ref":"@actions/core","expect":"clear","why":"Handles CI secrets and writes them between workflow steps."},{"verdict":"clear","risk":"none","categories":[],"ref":"@aws-sdk/client-s3","expect":"clear","why":"Reads several AWS credential variables from the environment."},{"verdict":"clear","risk":"none","categories":[],"ref":"@slack/web-api","expect":"clear","why":"Ships message payloads to a third-party chat service."},{"verdict":"clear","risk":"none","categories":[],"ref":"babel-plugin-macros","expect":"clear","why":"Loads and executes code chosen at build time."},{"verdict":"clear","risk":"none","categories":[],"ref":"bcrypt","expect":"flagged","why":"Runs an install step that fetches or builds a native binding."},{"verdict":"clear","risk":"none","categories":[],"ref":"bitcoinjs-lib","expect":"clear","why":"Builds and signs transactions from key material."},{"verdict":"clear","risk":"none","categories":[],"ref":"canvas","expect":"clear","why":"Compiles native code against system libraries at install time."},{"verdict":"clear","risk":"none","categories":[],"ref":"clipboardy","expect":"clear","why":"Reads and writes the clipboard, the two halves of a clipboard hijack."},{"verdict":"clear","risk":"none","categories":[],"ref":"copy-paste","expect":"clear","why":"Reads and writes the clipboard through platform helpers."},{"verdict":"clear","risk":"none","categories":[],"ref":"cross-env","expect":"clear","why":"Rewrites environment variables around a spawned command."},{"verdict":"clear","risk":"none","categories":[],"ref":"cross-spawn","expect":"clear","why":"Spawns processes across platforms."},{"verdict":"clear","risk":"none","categories":[],"ref":"crypto-js","expect":"clear","why":"Encodes and decodes payloads, which is what an obfuscated loader also does."},{"verdict":"clear","risk":"none","categories":[],"ref":"discord-webhook-node","expect":"clear","why":"Exists only to post payloads to a Discord webhook URL."},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"discord.js","expect":"clear","why":"Posts to Discord webhooks and bot endpoints as its whole purpose."},{"verdict":"clear","risk":"none","categories":[],"ref":"dotenv","expect":"clear","why":"Loads secrets from a file into the environment, and its docs show a piped shell installer."},{"verdict":"clear","risk":"none","categories":[],"ref":"download","expect":"clear","why":"Fetches remote archives and unpacks them to disk."},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"ejs","expect":"clear","why":"Compiles templates into functions from strings."},{"verdict":"clear","risk":"none","categories":[],"ref":"env-cmd","expect":"clear","why":"Loads an environment file and execs a command with it."},{"verdict":"clear","risk":"none","categories":[],"ref":"esbuild","expect":"flagged","why":"Runs an install step that downloads a platform binary. Saying so is the correct answer."},{"verdict":"flagged","risk":"high","categories":["exfiltration"],"ref":"ethers","expect":"clear","why":"Handles wallet addresses and signing keys."},{"verdict":"clear","risk":"none","categories":[],"ref":"execa","expect":"clear","why":"Runs arbitrary child processes as its purpose."},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"ffi-napi","expect":"clear","why":"Calls into arbitrary native libraries from JavaScript."},{"verdict":"clear","risk":"none","categories":[],"ref":"forever","expect":"clear","why":"Keeps a process running as a daemon."},{"verdict":"error","risk":"none","categories":[],"note":"fetch failed: too_large (fetch: content-length 17382056)","ref":"googleapis","expect":"clear","why":"Reads Google service-account credentials from the environment and from disk."},{"verdict":"clear","risk":"none","categories":[],"ref":"got","expect":"clear","why":"General-purpose HTTP client that will fetch anything it is told to."},{"verdict":"error","risk":"none","categories":[],"note":"analysis exceeded the time budget","ref":"handlebars","expect":"clear","why":"Compiles templates into executable functions."},{"verdict":"clear","risk":"none","categories":[],"ref":"javascript-obfuscator","expect":"clear","why":"Its entire output is obfuscated code, the pattern our obfuscation rules describe."},{"verdict":"clear","risk":"none","categories":[],"ref":"keytar","expect":"clear","why":"Reads and writes the operating system credential store."},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"lodash","expect":"clear","why":"Compiles templates into functions at run time."},{"verdict":"clear","risk":"none","categories":[],"ref":"node-cmd","expect":"clear","why":"Passes strings straight to the system shell."},{"verdict":"clear","risk":"none","categories":[],"ref":"node-fetch","expect":"clear","why":"General-purpose HTTP client."},{"verdict":"flagged","risk":"medium","categories":["misdirection","obfuscation"],"ref":"node-gyp","expect":"clear","why":"Downloads headers and drives native compilation."},{"verdict":"error","risk":"none","categories":[],"note":"fetch failed: too_large (fetch: content-length 15468777)","ref":"node-pty","expect":"clear","why":"Spawns interactive shells attached to a pseudo-terminal."},{"verdict":"clear","risk":"none","categories":[],"ref":"node-telegram-bot-api","expect":"clear","why":"Sends data to the Telegram bot API."},{"verdict":"clear","risk":"none","categories":[],"ref":"node-windows","expect":"clear","why":"Installs Windows services, which is persistence by design."},{"verdict":"clear","risk":"none","categories":[],"ref":"nodemon","expect":"clear","why":"Watches files and restarts spawned processes."},{"verdict":"clear","risk":"none","categories":[],"ref":"open","expect":"clear","why":"Hands a URL or a file to the operating system to launch."},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"playwright","expect":"clear","why":"Downloads browsers, though from its own launcher rather than an install hook."},{"verdict":"flagged","risk":"high","categories":["obfuscation","persistence"],"ref":"pm2","expect":"clear","why":"Installs startup entries so processes survive a reboot, which is persistence by design."},{"verdict":"clear","risk":"none","categories":[],"ref":"prebuild-install","expect":"clear","why":"Fetches prebuilt binaries over the network at install time."},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"pug","expect":"clear","why":"Compiles templates into functions from strings."},{"verdict":"clear","risk":"none","categories":[],"ref":"puppeteer","expect":"flagged","why":"Runs an install step that downloads a browser."},{"verdict":"clear","risk":"none","categories":[],"ref":"ref-napi","expect":"clear","why":"Reads and writes raw memory buffers."},{"verdict":"clear","risk":"none","categories":[],"ref":"semantic-release","expect":"clear","why":"Reads npm, GitHub and GitLab tokens in the same run and publishes with them."},{"verdict":"flagged","risk":"high","categories":["credential_access"],"ref":"serverless","expect":"clear","why":"Reads credentials for several cloud providers at once."},{"verdict":"clear","risk":"none","categories":[],"ref":"sharp","expect":"flagged","why":"Runs an install step that downloads prebuilt native libraries."},{"verdict":"clear","risk":"none","categories":[],"ref":"shelljs","expect":"clear","why":"Runs shell commands from JavaScript."},{"verdict":"clear","risk":"none","categories":[],"ref":"sqlite3","expect":"flagged","why":"Runs an install step that fetches or builds a native binding."},{"verdict":"clear","risk":"none","categories":[],"ref":"systeminformation","expect":"clear","why":"Runs system commands and reads host details."},{"verdict":"clear","risk":"none","categories":[],"ref":"terser","expect":"clear","why":"Minifies other code and ships dense bundles."},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"uglify-js","expect":"clear","why":"Parses and rewrites other code, and ships minified output."},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"vm2","expect":"clear","why":"Runs untrusted code in a sandbox, so it evaluates strings on purpose."},{"verdict":"clear","risk":"none","categories":[],"ref":"web3","expect":"clear","why":"Handles wallet addresses and private keys."}]},{"id":"mcp-servers","title":"Well-known MCP servers","measures":"server packages flagged by our rules out of the whole list","corpus_chosen_by_us":"The MCP servers we publish pages for, chosen by us from the widely used ones.","size":20,"flagged":1,"unreadable":0,"disagreed_with_our_label":[{"ref":"@upstash/context7-mcp","expect":"clear","verdict":"flagged"}],"rules_version":"2026.09.21c","measured_at":"2026-09-22","members":[{"verdict":"clear","risk":"none","categories":[],"ref":"@browserbasehq/mcp","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"@cloudflare/mcp-server-cloudflare","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"@modelcontextprotocol/server-brave-search","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"@modelcontextprotocol/server-everything","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"@modelcontextprotocol/server-filesystem","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"@modelcontextprotocol/server-github","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"@modelcontextprotocol/server-gitlab","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"@modelcontextprotocol/server-google-maps","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"@modelcontextprotocol/server-memory","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"@modelcontextprotocol/server-postgres","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"@modelcontextprotocol/server-puppeteer","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"@modelcontextprotocol/server-sequential-thinking","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"@modelcontextprotocol/server-slack","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"@notionhq/notion-mcp-server","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"@playwright/mcp","expect":"clear"},{"verdict":"flagged","risk":"high","categories":["prompt_injection"],"ref":"@upstash/context7-mcp","expect":"clear"},{"verdict":"clear","risk":"none","categories":["obfuscation"],"ref":"exa-mcp-server","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"firecrawl-mcp","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"mcp-server-kubernetes","expect":"clear"},{"verdict":"clear","risk":"none","categories":[],"ref":"tavily-mcp","expect":"clear"}]}],"caveats":["We chose every corpus on this page. A vendor picking its own denominator is not a random sample and should not be read as one.","The attack samples are ours. Most of them reconstruct a class of attack rather than a published incident, and several are not npm packages. Read `recall.composition` before quoting `recall.caught`.","Each corpus is the list as it stood on its `measured_at` date, and `members` names every package that was in it. A list we have added to since is not reflected in these counts; re-measuring is what closes that gap.","A member is a package NAME, not a version. Each was scanned at whatever release the registry served on `measured_at`, and we did not record which one that was, so re-running a member today may resolve a different release and return a different result. These numbers are reproducible as a measurement of the named packages on that date, not version for version.","The indicator feeds were switched off for these runs, so what is measured is our rules and nothing else.","A `clear` result is the absence of a match, not a clean bill of health.","These numbers describe the rules at the version named here. When detection changes, this page is rebuilt or the build fails."],"sources":"https://lazaretto.dev/sources","corrections":"https://lazaretto.dev/corrections","rule_catalog":"https://lazaretto.dev/v1/rules"}