DEV Community

secleeman
secleeman

Posted on Originally published at zenn.dev AI-assisted

I Built a Vulnerability Triage Tool Without Knowing What EPSS or KEV Meant

In the last two posts I described how, unable to read code, I delegated implementation to Claude Code, built a vulnerability triage CLI called triage-lens, and then let it run Phase 2 overnight while I slept. Both posts ended with the same promise: next time, the substance. How EPSS and CISA KEV fit together.

I sat down to write that third post and stopped.

I cannot explain what EPSS is. Or KEV. Honestly, even CVSS is shaky. My own tool runs on this data, passes 373 tests, and has shipped as v0.2.0. And I could not have defined the three scores it is built on.

I could fake it. An AI could draft a plausible explainer in an hour. But the spine of this series has been admitting what I don't understand and then showing how quality gets assured anyway. So this post delivers the promised explanation while starting from the awkward fact that the person who built the tool understood it least.

(Translation of my Japanese article on Zenn.)

What I did have: the memory of the floor

One thing in my defense. I didn't know the score definitions, but I knew exactly what a score-only list does to a team.

Years ago I worked as a PMO on automotive software development. Nothing to do with security; my job was keeping delivery on track. The engineering side's honest position was simple. We both know fixing everything is impossible, so give us an order.

Forwarding a list of findings from right to left isn't management. It exhausts the team and fixes nothing. Deciding the order is the manager's actual job, and we had no basis for it. Half my motivation for building triage-lens was that memory. The theory came later. The hunger for an ordering tool came first.

The three words, as the AI explained them to me

So, belatedly, I had the AI break it down until I could restate it myself. The weather analogy is the one that stuck.

CVSS is severity. A 0-to-10 score, a shared global ruler. It measures how much it hurts if you fall. It says nothing about whether you will fall. This is the misunderstanding at the center of everything: a list of several hundred CVSS 9.8 findings is a list of painful cliff heights, not a list of places about to collapse.

EPSS is the forecast. FIRST.org computes, with machine learning, the probability that a vulnerability will actually be exploited in the next 30 days, refreshed daily. It's the chance of rain. Plenty of high-CVSS vulnerabilities carry a tiny EPSS, and only a small fraction ever get exploited at all.

CISA KEV is the record. A catalog maintained by the US security agency CISA of vulnerabilities with confirmed exploitation in the wild. Not a forecast. A log of where it already rained.

And the layering works like this. Sort by pain alone and everything looks top priority. Add probability and add fact, and a short list of things to look at first rises out of the pile. In triage-lens, the top rank P0 means listed in KEV: it already rained there, no debate. P1 means both likely and painful, EPSS at or above 0.1 with CVSS at or above 7.0. Everything else falls in behind.

Written out, it is simple arithmetic. I understood it after my tool was already public.

How I trusted a thing I didn't understand

This is the part I actually wanted to write. How does someone with no theory trust a tool that runs on theory?

Looking back, every check I ran lived outside the theory. Take the CVEs ranked P0, download CISA's actual KEV catalog without going through the tool, and compare. The three P0 findings (Log4Shell, Heartbleed, Spring4Shell) were really listed. The nine ranked P1 or lower were really absent. For EPSS, hit the public API in a browser and confirm the numbers match.

I still don't know how EPSS is calculated. But whether the tool's claims agree with the world's facts can be verified with zero theory. Understanding and verification are different skills, and verification is the one you need first.

Understanding caught up later, and honestly it landed better for the delay. After fighting defects in the failure paths, like the one that displayed a missing exploit probability as "low," the difference between CVSS and EPSS finally meant something. If I had read the textbook first, it would have gone in one ear and out the other.

The order: verify from day one, understand as you go

My conclusion. When you use something you don't understand, the thing to secure first is not understanding. It is verification. As long as you can check the tool's claims against outside facts, it stays trustworthy while your understanding catches up. Understanding without verification, on the other hand, is indistinguishable from the plausible explainer an AI can write in an hour.

The PMO I used to be wanted exactly this. Explain the theory later; give me a defensible order now. I think triage-lens became the tool I wished someone had handed me back then.

The repository is public. The reason column on P0 rows says "listed in KEV, actively exploited" in plain words. That line is for people who can't read the scores yet. People like me, three weeks ago.

https://github.com/secleeman/triage-lens

Top comments (0)