AI picked your packages. Who’s checking them?
You're prompting an AI coding assistant. It scaffolds a Next.js app, suggests npm install framer-motion image-resize-cropper zustand, and you hit enter. Five seconds later you're writing the next feature. By Friday you've shipped four side projects, each with sixty dependencies you didn't pick.
This is fine. This is how a lot of work happens now. But it has a security shape worth being honest about.
The three things that changed when AI started picking your packages
1. You install more packages, faster. A pre-AI dev typed npm install <name> after reading a tutorial or finding it on npm. Now the package list lands in your editor before you've thought about it. The decision boundary moved from "should I install this?" to "did I notice the install line at all?"
2. AI hallucinates package names. This is the headline risk. Large models occasionally invent package names that sound right but don't exist. Attackers monitor model outputs, see the popular hallucinations, then register those names on npm/PyPI with a payload. The technical term is slopsquatting. Researchers documented over 200 hallucinated package names that AI assistants suggested and attackers registered within weeks. If you don't read the install command before you run it, you install whatever the AI imagined.
3. Your dev machine is a high-value target. Vibe coding works because everything is on your laptop: GitHub tokens in ~/.netrc, AWS keys in ~/.aws/credentials, npm publish tokens in ~/.npmrc, browser cookies in your profile, SSH keys in ~/.ssh, the .env of every side project. A postinstall script runs with your user's permissions. It can read all of it.
"I'll read the code before I run it"
You won't. Nobody does. The framer-motion you just installed has 400 transitive dependencies. Reading them is more work than the feature you're trying to ship. The whole point of npm is that you don't read the code.
Old advice that doesn't work in vibe mode:
- Pin your dependencies. You're scaffolding, not maintaining.
- Use a lockfile. You blew it away three projects ago.
- Audit before install.
npm auditruns on CVE databases. The window between "malicious package goes live" and "CVE is filed" is hours to days. Slopsquats often never get filed at all.
What actually catches it
The shape of the fix is: check the package before any byte hits disk, and contain anything that slips past the check at install time.
A local proxy in front of npm/pip can:
- Catch the typo / slopsquat. If
framr-motionexists butframer-mootionis suspicious (registered last week, no downloads, name distance of 1 from a popular package), block it. You see a clean refusal, retry with the right name, move on. - Score the package. Twelve signals — known CVEs, maintainer changes between versions, install-script risk, hidden payloads, native-binary symbol scan, typosquat distance, dependency-confusion against your protected scopes. Low score → refused before download.
- Sandbox what gets through. If you install something the gate let through, an OS-level sandbox wraps the install. The postinstall script can't read
~/.sshor~/.aws, can't write to~/.bashrc, can't phone home. Even if the gate is wrong, the blast radius is the project folder.
Same npm install. Same lockfiles. Same workflow. Just a layer underneath that refuses the bad ones and contains the suspicious ones.
The vibe coder's threat model, concretely
If you ship side projects with AI assistance:
- Most likely incident: you install a slopsquat. Either the AI suggested a name that doesn't exist (so the install just fails — annoying but safe), OR it suggested a name that an attacker registered (you get popped). The attacker's goal is the credentials on your laptop. Veln's gate refuses these at install time because typosquat distance and dormant-revival both fire on freshly-registered packages with confusable names.
- Higher-impact incident: a legitimate package you use gets hijacked between v2.3.7 and v2.3.8. You run
npm installfor an unrelated reason and pull the bad version. Cross-version maintainer-drift and file-tree-drift signals catch this; if they miss, the sandbox blocks the postinstall from reading your credentials. - Hardest to defend: the package is benign on your machine but malicious at runtime in production. No install-time tool catches this; the gate's pre-download block is the only defense, and it works only if the malicious version is scored badly. Veln does what it can here; nobody can do more without rewriting how require/import works.
What it costs you
Two commands, once per machine:
veln onboarding
veln wrapper on
After that, every npm install / pip install / yarn add / pnpm add / bun add / uv pip / poetry add / pipx install routes through the gate and the sandbox. You don't change your prompt to your AI assistant. You don't change your habits. The check happens at the registry layer, transparent to your workflow.
The first time you hit a false positive, you get an interactive prompt with the exact path the install tried to touch and four options: deny, allow once, allow for this project, allow globally. The default is deny — because for a vibe coder, "I'm not sure" should mean "I'm not running it."
The honest bit
Veln won't make AI stop hallucinating package names. It won't read code for you. It won't replace your taste. What it does is make the install command — the one you stopped paying attention to — into a check that runs every time, without slowing you down.
If you let AI pick your packages, you need something that picks the bad ones back out. This is that.