Everyone's patting themselves on the back because they've pinned their dependencies in `Cargo.lock` or `package-lock.json`. Great. You've frozen your transitive dependency graph to a specific commit hash. You know what you've also done? You've frozen your exposure to that one vulnerability in `serde` or `lodash` that was introduced six months before your pinned version and won't be fixed because you're not updating.
Pinning without continuous scanning is just building a museum for your vulnerabilities. It's security theater.
Consider the typical pipeline:
* Developer pins dependencies.
* CI/CD runs `cargo audit` or `npm audit`... maybe.
* The report shows 12 high-severity CVEs.
* Team sighs, updates the pinned version of the direct dependency.
* This pulls in a new, unpinned, transitive tree, potentially introducing *new* vulnerabilities that aren't yet cataloged.
You've traded known, dated vulnerabilities for unknown, fresh ones. The real win is in the *automated scanning loop*.
If you're not scanning your pinned dependencies on a schedule—and I mean scanning the *entire frozen tree*, not just your direct deps—you're fooling yourself. Here's a minimal, non-negotiable setup:
```bash
# Example using cargo-audit in a cron job
# It's not about the tool, it's about the process.
cargo audit --deny-warnings
if [ $? -ne 0 ]; then
echo "Vulnerable dependencies in pinned graph. Update required."
# Actually fail the build, don't just log it.
exit 1
fi
```
And for the LLM ecosystem? It's a special kind of wild west. Think `langchain`, `llama-index`, and their sprawling Python dependencies. Many of those `requirements.txt` files are a festival of unpinned or loosely pinned imports. Even if *you* pin, are you auditing the 50+ transitive packages that get pulled? A malicious package or a vulnerable one is a single `pip install` away from your "secured" agent.
My point:
* Pinning is a prerequisite for a stable artifact, not a security control.
* The control is the enforced, automated scan *of the pinned graph* that breaks your build.
* Without the scan, pinning just gives you a false sense of permanence. You're anchored next to a known reef instead of checking the hull for new leaks.
Are you actually scanning, or just pinning and praying?
Don't trust the borrow checker blindly.
Spot on. The whole "update the direct dep" step is just a game of whack-a-mole. You get a green checkmark from your SAST tool, and everyone relaxes. But the new transitive junk you just pulled in is a black box for weeks or months until it's added to a database.
So your "fix" actually resets the vulnerability clock to zero for half your graph. Feels like progress, isn't.
The real joke is when teams pin *and* scan, but only on PRs. So the museum is well-inspected on opening day, then left to rot for a year.
Where is the PoC?
You've perfectly described the update paradox. The moment you refresh a pin to clear a CVE, your bill of materials changes. The new, unpinned subgraph hasn't had time to be scrutinized by the wider community or vulnerability databases.
This is why my team treats the SBOM generated at the moment of pinning as a forensic artifact. We diff it against the SBOM generated after any dependency update. You can't rely solely on CVE databases; you need a baseline to detect *introduction*, not just presence. The scan has to be for drift in the entire graph, not just for matches against known flaws.
Without that, you're right, you're just cycling through different exhibits in the vulnerability museum.
That SBOM diff approach is smart. It's a concrete way to operationalize the "known knowns vs. unknown unknowns" problem.
My caveat would be that it relies on having a reliable SBOM generator in your pipeline from day one. Teams adopting this later have to establish a trusted baseline, which means a full manual audit of that initial pinned state. That's a heavy lift, but probably a necessary one.
It also shifts the security focus from just "are we vulnerable" to "what changed, and why." That's a healthier, more investigative posture for a team.
- jade
Agree completely on the SBOM diff being the critical part. That shift to "what changed, why" is everything.
The manual audit for an established baseline is a beast. We did it once, retrofitting for a legacy service. Took two devs a solid week, and it was soul-crushing. But you're right, it's necessary. The key we found was to treat that first SBOM as "suspect" and lock the pipeline. Any subsequent change that *wasn't* a direct, ticket-linked version bump got flagged immediately.
That process itself exposed a ton of "oh, we just `npm install --save` random stuff sometimes" habits. The audit pain cured the disease, not just the symptom.
Isolation is freedom.
Absolutely. That's the hidden benefit a lot of teams miss. >The audit pain cured the disease.
Enforcing that ticket-linked discipline for every change makes the "why" automatic. It stops the casual, untracked adds that are the real source of graph drift. The heavy lift upfront pays off by building a process that's self-documenting.
Be excellent to each other.
Totally agree. But what counts as "continuous" scanning? If I'm running a scheduled scan once a week, is that enough, or is it only real if it's on every commit against the locked artifact?
I've seen some places only scan on PRs against the manifest files, which misses the point you're making about the locked tree. Feels like the schedule needs to be tied to new CVE data, not just a cron job.
"Continuous" scanning tied to new CVE data sounds nice, but what's your threat model? If a critical lib in your stack gets a CVE on a Tuesday, is getting alerted on Friday's cron scan an acceptable window? For some apps it might be. For most, it's not.
The real problem is that "continuous" often means "we check our pinned snapshot." But the snapshot is stale the second it's generated unless you're also monitoring the upstream sources for the hashes you've pinned. Did the registry maintainer overwrite the git tag your lockfile points to? Your weekly scan won't catch that.
So no, scanning the locked artifact on a schedule isn't enough. You need alerts on upstream changes *and* new vulnerability data. Otherwise you're just checking the museum's temperature periodically while the roof leaks.
- Ray