Dev.to Security 🔐 Cybersecurity 👁 1 📖 39 min read

Learning to Triage Vulnerabilities and Their Real Product Impact — or How Product Security Turns a Finding into a Risk Decision

A practical playbook: triage → applicability → exposure → reachability → exploitability → blast radius → business impact → treatment → verification. When I was working in SecOps, one of the most useful lessons I learned

Learning to Triage Vulnerabilities and Their Real Product Impact — or How Product Security Turns a Finding into a Risk Decision

A practical playbook: triage → applicability → exposure → reachability → exploitability → blast radius → business impact → treatment → verification.

When I was working in SecOps, one of the most useful lessons I learned was painfully simple: a red CVSS number or a “High Impact” scanner alert is not, by itself, proof of a real product risk. If the dashboard is screaming 9.8 in bright red, congratulations — you have a signal. The thinking part still belongs to you.

A scanner can tell you that a vulnerability has a CVSS score of 9.8. An SCA tool can flag a vulnerable dependency. SAST can identify a potentially dangerous sink. DAST can confirm behavior in a running application. A CNAPP can surface a cloud misconfiguration. And a bug bounty researcher can send you a PoC and, quite reasonably, ask to get paid for the trouble. :)

That is where the real work starts. The scanner has done its job. Now Security has to do something slightly less glamorous: think.

The job of a security engineer is not to forward a finding to developers with the message, “Critical. Fix ASAP.” and then vanish into Slack like a smoke grenade. The job is to understand what was found, whether it actually applies to your product, whether the vulnerable path is reachable, who can attack it, what privileges an attacker gains, where they can pivot next, what the business can realistically lose, and which response reduces risk fastest.

That is the mindset I want to share here — the part of vulnerability management that begins after the scanner has finished being dramatic.

Let’s take the whole thing apart, piece by piece. No magic. No “the tool said so.” Let’s go.

This article is written for three audiences at once:

  • people entering Product Security or AppSec who want to understand the full process from scanner alert to decision;
  • Senior Security Engineers who need to own triage and risk decisions, not just detection;
  • Technical Leads and Security Leads who need a repeatable vulnerability-management process that engineering and business stakeholders can trust.

The core idea is straightforward:

CVSS is a severity signal. Remediation priority appears only after you add context.

That context is not one extra Jira field. It is a chain of evidence: applicability, exposure, reachability, exploitability, threat intelligence, asset criticality, blast radius, compensating controls, business impact, and confidence.

DISCLAIMER

The architectures and some scenarios in this article are intentionally simplified as teaching models. Real CVEs and vendor statements are called out separately. A reachability verdict should never be based on one scanner signal alone: the quality of the decision depends on the evidence you have and how well you understand the actual runtime environment.

Field card: the triage map I would keep in front of me

If I had to compress the entire mindset into one screen, this is the card I would use:

FINDING
   |
   v
[Real / Valid?]
   |
   v
[Affected in our build / runtime?]
   |
   v
[Where is it deployed?]
   |
   v
[Who can reach it?]
   |
   v
[Is the vulnerable path reachable?]
   |
   v
[Possible -> Feasible -> Weaponized -> Active?]
   |
   v
[What identity / privileges does compromise give?]
   |
   v
[What can the attacker reach next?]
   |
   v
[Business impact / blast radius]
   |
   v
[Which control can break the path now?]
   |
   v
[Priority -> Treatment -> Owner -> SLA / Expiry]
   |
   v
[Verify -> Reassess -> Reopen if assumptions change]

This is not a checklist created so we can admire another checklist. It is a compact reasoning model — adapt it to your stack, architecture, product, and trust model. If I cannot answer one of these questions, I write Unknown. Security gets weird very quickly when uncertainty is magically rebranded as Low risk just because nobody had time to investigate it.

Another useful operational signal from real programs is age / time at risk: how long a finding has existed in production and how long the asset has remained exposed. Age does not magically turn a Medium into a Critical, but it matters for queue management, breached SLAs, and accumulated security debt — exactly the kind of thing a Lead or Head eventually has to explain when the backlog starts developing its own ecosystem.

Why the old “CVSS = Priority” model breaks down

Ten years ago, the classic vulnerability-management workflow often looked like this:

Scanner -> CVE -> CVSS -> SLA -> Patch

A typical policy might say:

CVSS 9.0-10.0 -> Critical -> fix in 24/48h
CVSS 7.0-8.9  -> High     -> fix in 7 days
CVSS 4.0-6.9  -> Medium   -> fix in 30 days
CVSS < 4.0     -> Low      -> backlog

That is beautiful for reporting. Neat colors, neat SLAs, neat executive slides. For actual Product Security, though, it is way too crude. Reality, annoyingly, refuses to fit into four severity buckets — and this is where an expert lens starts earning its keep.

FIRST explicitly states in the CVSS v4.0 guidance that CVSS-B measures severity, not risk. CVSS v4.0 separates Base, Threat, Environmental, and Supplemental metrics, which is effectively an acknowledgement that intrinsic technical severity is only one layer of the decision.

Practical examples:

  • A CVSS 9.8 issue in a library that your application never calls may be lower operational priority.
  • A CVSS 6.5 authorization flaw on an Internet-facing API that leaks cross-tenant data may be far more dangerous to the business.
  • A CVSS 8.x issue on an internal CI/CD controller can become P0 if that controller has signing keys, registry write access, production deployment tokens, and Kubernetes privileges.
  • A CVSS 10.0 issue in a package that never makes it into the runtime artifact may turn out to be a false positive or a valid not_affected conclusion for that product.

So I prefer to reason about priority as:

Priority = f(
    Technical Severity,
    Applicability,
    Exposure,
    Reachability,
    Exploitability,
    Threat Intelligence,
    Asset Criticality,
    Blast Radius,
    Compensating Controls,
    Business Impact,
    Confidence
)

This is not an arithmetic formula. Please do not multiply ten subjective coefficients until a magical 8.73 falls out of Excel and suddenly becomes “science.” These are the questions I want answered before I call something Critical for us.

Field vocabulary: the language of practical vulnerability triage

If you are new to Product Security, the terminology can look like someone dropped the alphabet into Jira: CVE, CWE, CVSS, EPSS, KEV, VEX, SCA, SAST, DAST. At first it sounds like corporate magic. It really is not. Each term answers a fairly concrete question, so let’s crack it open.

Term What it means in real work
Finding Any security signal: CVE, SAST finding, DAST issue, misconfiguration, pentest finding, bug bounty report
CVE Identifier for a publicly disclosed vulnerability
CWE Weakness class such as SSRF, path traversal, auth bypass, deserialization, etc.
CVSS Standardized technical-severity scoring framework
SCA Software Composition Analysis — identifies vulnerable third-party dependencies
SAST Static Application Security Testing — analyzes source/IR without running the app
DAST Dynamic Application Security Testing — tests a running application
SBOM Software Bill of Materials — inventory of product components
VEX Vulnerability Exploitability eXchange — machine-readable statement about vulnerability applicability/exploitability in a specific product
EPSS FIRST model estimating the probability that a CVE will be exploited in the wild within the next 30 days
KEV CISA Known Exploited Vulnerabilities Catalog — vulnerabilities with confirmed exploitation in the wild
PoC Proof-of-concept exploit or exploitation demonstration
Pre-auth / unauth Exploitable before authentication / without an account
Exposure How reachable the system is: Internet, partner, VPN, internal, namespace-local, offline
Reachability Whether attacker-controlled execution/data can reach the vulnerable code/function/sink
Entry point HTTP route, queue consumer, RPC method, webhook, file parser, CLI command, etc.
Sink Dangerous operation: command execution, SQL query, deserialization, file write, outbound request, etc.
Source-to-sink Flow of untrusted input into a dangerous sink
Call graph Graph of function calls used for code-level reachability analysis
Taint flow Tracking untrusted data through the program
Attack path Practical path from attacker entry point to security impact
Exploit chain Multiple primitives or vulnerabilities chained into one scenario
Blast radius Scope of damage after successful compromise
Pivot / lateral movement Moving from one compromised system to additional systems
Crown jewel Asset with outsized value: CI/CD, IAM, secrets, signing infrastructure, production control plane
Compensating control Control that genuinely breaks an attack path or reduces impact when a direct fix is not immediate
Residual risk Risk that remains after mitigation
Risk acceptance / exception Formal temporary acceptance with owner, rationale, evidence, and expiration
SLA Agreed remediation timeline for a risk class
ASPM Application Security Posture Management — correlation of AppSec signals and context
CNAPP / CSPM Cloud-native/cloud posture tooling that adds cloud and identity context

Memorizing the acronym is not the goal. You do not get bonus points for saying VEX three times in a meeting. Knowing which decision the signal helps you make is what matters.

My engineering mindset: do not “close a CVE”; prove the risk

When I investigated a vulnerability, I tried not to begin with:

“We have a Critical. We need a dev fix. Put it in the sprint.”

That sentence is usually where useful context goes to die.

I started with a different question — usually to myself first, and then to the SecOps / engineering folks who actually knew the system:

“What exactly has to happen for an attacker to turn this finding into real impact?”

That question changes the quality of the conversation immediately.

Instead of a red card in a dashboard, you build an attack story:

Actor
  -> Entry point
  -> Trust boundary
  -> Vulnerable component/function
  -> Required privileges/configuration
  -> Exploit primitive
  -> Initial impact
  -> Pivot
  -> Crown jewel / data / production
  -> Business consequence

If I cannot sketch that chain, triage is probably not finished. I may have a finding, but I do not yet have a defensible risk story. So I keep digging: more evidence, more docs, more conversations — and these days, yes, sometimes I will bounce the reasoning off an AI assistant too. The point is not who you ask. The point is not stopping at the first red number.

Eight questions I ask before assigning priority

This is the part where the finding stops being a colored rectangle and starts becoming an engineering problem.

1. Is the finding real?

Start with a sanity check:

  • Is the package and version correct?
  • Is the SBOM stale?
  • Is the fingerprint a false positive?
  • Does the binary or image that actually runs fall into the affected range?
  • Does the OS/distro/build matter?
  • Is this a vendor-patched package that retained an upstream-looking version string?
  • Is the dependency present only in the build stage but absent from the runtime image?

Bad triage starts when a team spends two days emergency-patching a CVE that is not even present in the production artifact. Few things build character faster than discovering that fact after the rollback meeting.

2. Where does the component actually live?

Next, establish deployment context.

repo -> build -> image -> registry -> Kubernetes -> pod -> service -> route

You need to know:

  • dev, test, staging, or production;
  • public or internal;
  • customer-facing or back-office;
  • container, VM, serverless, or bare metal;
  • ephemeral worker or long-lived controller;
  • whether it holds state, secrets, or customer data;
  • which identities and service accounts are attached to it.

This is where asset criticality begins. And yes, man, having a reasonably clear map of the product and infrastructure in your head helps a lot.

3. What is the exposure?

Exposure is more nuanced than “is port 443 on the Internet?”

A useful mental model is:

Internet unauthenticated
        ↓
Internet authenticated
        ↓
Partner / customer private network
        ↓
VPN / corporate network
        ↓
Internal service-to-service
        ↓
Namespace / host local
        ↓
Offline / build-only

An internal system can be more dangerous than a public endpoint if it has powerful downstream privileges.

A Jenkins controller might be VPN-only but still hold:

  • GitLab tokens;
  • kubeconfig credentials;
  • registry credentials;
  • cloud roles;
  • artifact signing keys.

“Internal only” is not an automatic downgrade. Internal is a network location, not a security control. A CI server behind VPN with production credentials can be far more interesting to an attacker than a boring public brochure site.

4. Is the vulnerable path reachable?

Write this one down: package presence is not exploitability. For vulnerability triage, that is close to an axiom. This is where modern SCA and Product Security get much more interesting.

An SBOM tells me the package is in the room; it does not prove the package committed the crime. Use the evidence ladder below as a cheat sheet.

I like to think in terms of an evidence ladder.

Reachability evidence ladder

Level Evidence What we actually know
L0 — Presence package/version appears in SBOM component exists
L1 — Imported/Linked application imports or links it dependency is used somewhere
L2 — Function reachability call graph reaches affected symbol vulnerable function may be invoked
L3 — Source-to-sink taint/data-flow from attacker input to vulnerable sink attacker-controlled data may reach the operation
L4 — Route/exposure entry point is published through trust boundaries attacker can initiate the flow
L5 — Runtime evidence tracing, coverage, eBPF, telemetry confirms execution path path has executed in the deployed environment

The higher the level of evidence, the stronger the conclusion. Package present and attacker-controlled input reached the affected function in runtime are not the same caliber of evidence, even if a dashboard puts both findings in the same red box.

But the reverse matters too: failing to find a static path does not always prove the code is impossible to reach. Reflection, dynamic loading, plugin systems, native calls, dependency internals, and runtime code generation can defeat simplistic call-graph analysis.

So a mature verdict is not:

NOT REACHABLE = SAFE

It is closer to:

No reachable path found with current evidence; confidence: Medium. Reassess if feature/configuration/runtime changes.

Tooling is moving in this direction. OSV-Scanner supports call analysis and can distinguish vulnerabilities affecting called code from findings where the affected code path was not observed. OWASP dep-scan also supports reachability-aware prioritization and VEX-oriented workflows.

5. How weaponizable is the issue?

Technical severity is not enough. That is another one worth burning into memory. A scary score without a workable exploit path and a modest score with a cheap, automatable attack are having very different days.

I look at:

  • public PoC availability;
  • whether a functional exploit exists;
  • exploit reliability;
  • required prerequisites;
  • pre-auth vs authenticated exploitation;
  • whether mass scanning is easy to automate;
  • CISA KEV status;
  • EPSS probability and percentile;
  • vendor warnings about active exploitation;
  • threat-intelligence reporting.

EPSS: probability != percentile

There is one little trap here that trips up people who already work with vulnerability data: EPSS probability and EPSS percentile are not the same thing. Please do not mix them. The labels look close enough to cause trouble, and they mean very different things.

  • Probability is the model-estimated probability that exploitation will be observed in the next 30 days. A value of 0.10 means roughly 10%, not “0.1 out of 10.”
  • Percentile is the relative rank of that probability across the CVEs currently scored by FIRST. A percentile of 0.95 means the score is higher than roughly 95% of the current population — not a 95% probability of exploitation.

Because most CVEs are never observed being exploited, the distribution is heavily skewed toward zero. That means a probability that looks small at first glance can still sit surprisingly high in the percentile ranking.

I like to keep both values together:

EPSS probability:  0.10 (10%)
EPSS percentile:   0.95 (95th percentile)
EPSS checked_at:   YYYY-MM-DD

checked_at matters because EPSS is updated daily. Threat signal is not a tattoo on the CVE. It changes.

And one more rule: do not multiply EPSS by CVSS and call the result a risk score. You will get a very impressive-looking number and no clear statistical meaning. Pretty math is still pretty math.

A useful distinction:
Possible — theoretically exploitable.
Feasible — practically exploitable.
Weaponized — working exploit/tooling is available.
Active — exploitation is happening in the wild.

Those states deserve different operational responses. Going deeper into exploit lifecycle and threat modeling would be another article, so I am not turning this one into a security encyclopedia.

6. What does the attacker get after the first step?

This is privilege context.

RCE in a pod does not automatically mean cluster compromise. RCE is not a teleport spell to cluster-admin. Context still matters.

Check:

  • UID/root vs non-root;
  • privileged container status;
  • Linux capabilities;
  • hostNetwork / hostPID / hostPath;
  • service account token;
  • Kubernetes RBAC;
  • cloud IAM role;
  • mounted secrets;
  • metadata-service access;
  • outbound egress;
  • control-plane access;
  • registry permissions;
  • CI/CD credentials.

These are very different incidents:

RCE in an isolated non-root pod

versus

RCE in a privileged deployment controller with cluster-admin

The primitive is similar. The risk is not. This is also one of those moments where you can usually tell who is Junior, who is Mid, and who has already been through enough production fires to think like a Senior.

7. What is the blast radius?

After initial access, I ask:

“What can the attacker do next?”

The first shell is often the least interesting part of the story.

Example:

Internet
   |
   v
[Nginx]
   |
   v
[API Pod]
   |
   +--> service account
   |
   +--> internal DB
   |
   +--> internal admin API
   |
   +--> container registry
   |
   +--> secrets

A vulnerability that causes a local DoS in one stateless replica is one risk.

A vulnerability that opens a path to:

  • cross-tenant data;
  • production secrets;
  • signing keys;
  • build infrastructure;
  • registry write access;
  • IAM privilege escalation;
  • production deployment;
  • customer PII;

is something else entirely. That is blast-radius analysis. And when those downstream paths include crown jewels, yes — the priority can jump fast.

8. What is the fastest way to break the attack path?

A critical mindset shift: remediation is not synonymous with patching. Patch is a treatment option, not a religion.

Patching is often the OK answer, but it is not the only answer.

The fastest risk reduction may be:

  • disable a feature flag;
  • remove a route;
  • remove Internet exposure;
  • disable a CLI;
  • deploy a WAF/gateway rule;
  • block egress;
  • deny access to metadata endpoints;
  • reduce IAM/RBAC;
  • remove a secret mount;
  • isolate a namespace;
  • roll back a component;
  • remove a vulnerable package;
  • rotate credentials;
  • deploy a vendor hotfix;
  • temporarily take a node or service out of rotation.

Then you perform the permanent fix safely. If you can break the attack path in 15 minutes and the permanent code change takes three days, there is no medal for leaving the door open while everyone waits for the elegant fix.

A strong Security Engineer influences not only what gets fixed, but how risk is reduced right now.

The full processing chain: from finding to decision

If I were onboarding a junior engineer, this is the workflow I would give them. Keep it as a cheat sheet until the sequence becomes muscle memory.

[SCA / SAST / DAST / CNAPP / Pentest / Bug Bounty / Vendor Advisory]
                              |
                              v
                    1. Intake / Normalize
                              |
                              v
                    2. Validate / Dedupe
                              |
                              v
                       3. Applicability
                              |
                              v
                  4. Exposure / Reachability
                              |
                              v
                5. Exploitability / Threat Intel
                              |
                              v
                 6. Asset / Identity / Blast Radius
                              |
                              v
                     7. Business Impact
                              |
                              v
                 8. Compensating Controls
                              |
                              v
                    9. Priority Decision
                              |
                              v
                 10. Treatment / Ownership
                              |
                              v
                    11. Fix Verification
                              |
                              v
               12. Evidence / Exception / Recheck

And this is the purpose of each stage:

Stage Main question Typical output
Intake Where did the signal come from? finding ID, source, asset
Validate Is it real and unique? confirmed / duplicate / false positive
Applicability Is our version/build/runtime affected? affected / not affected / unknown
Exposure Who can reach it? Internet / auth / VPN / internal
Reachability Can execution/data reach the affected path? route, call path, taint evidence
Exploitability Can this be exploited realistically today? PoC, EPSS, KEV, active exploitation
Blast radius What happens after compromise? identities, secrets, downstream systems
Business impact What does the business lose? data, money, uptime, compliance, trust
Controls What breaks the chain? WAF, segmentation, IAM, disabled feature
Priority How quickly do we need to act? P0/P1/P2/P3 or Critical/High/Medium/Low
Treatment What are we doing? patch, mitigate, contain, accept, avoid
Verification Did we actually reduce risk? retest / scan / telemetry evidence
Recheck What could invalidate the decision? expiration, reopen triggers

What a good triage ticket looks like

One of the most valuable Senior Engineer skills is turning noisy scanner output into a concise, decision-ready record.

A template I would use looks like this:

Finding ID:
Source: SCA / SAST / DAST / Pentest / Vendor / Bug Bounty
Asset / Service:
Environment: prod / staging / dev
Owner:

CVE / CWE:
Affected component + version:
CVSS-B / vector:
EPSS probability / percentile:
CISA KEV: yes/no
Public PoC: yes/no/unknown
Active exploitation: yes/no/unknown

Exposure:
Authentication required:
Entry point:
Reachability evidence:
Exploit prerequisites:
Assessment confidence: High / Medium / Low

Runtime identity:
IAM / RBAC context:
Secrets available:
Downstream systems:
Blast radius:
Data classification:

Existing controls:
Control verification evidence:
Residual risk:

Final priority:
Recommended treatment:
Security owner:
Engineering owner:
Due date / SLA:
Exception expiry:
Reopen triggers:

Compare two handoffs.

Weak handoff

Critical CVE 9.8. Please patch ASAP.

Strong handoff

CVE-X is present in production image orders-api:v312. The package version is affected, but the vulnerable XML import function is not reachable from published routes; the feature is disabled, no call-graph path was found, and runtime tracing did not observe parser loading. The service is Internet-facing, but the affected route is not exposed. The CVE is not in KEV and no reliable public exploit was identified. Hypothetical impact is high because the service processes customer data. Priority: P2. Upgrade in the next release train. Record VEX not_affected/code_not_reachable with a 30-day expiration. Reopen if the import feature is enabled, the route is published, a reliable exploit appears, KEV status changes, or architecture changes.

The second version gives a Tech Lead something they can actually decide on. The first one was written by a junior, a bot, somebody already mentally at lunch — or something else is going on, and none of those options are especially comforting. :)

Severity, Risk, and Priority are different concepts

This distinction comes up constantly in interviews and real-world work — mostly because dashboards, tickets, and people love using these words as if they were interchangeable. They are not.

Severity

How serious the technical impact could be. CVSS is primarily here.

Risk

Likelihood + impact in the context of your organization.

Priority

How quickly you should act relative to other risks, delivery constraints, and available resources.

You can absolutely have:

High Severity + Low Reachability + Strong Controls = Medium Priority

or:

Medium Severity + Internet Exposure + High Exploitability + Crown Jewel Impact = Critical Priority

That is not inconsistency. That is the entire point of context-aware prioritization.

Risk Priority != Remediation Difficulty

This is a Lead-level nuance that tends to disappear the moment Security and Engineering start negotiating timelines and someone discovers the fix is inconvenient.

A vulnerability does not become less risky just because it is difficult to fix. Hard to fix is not a severity metric. Remediation difficulty changes the treatment plan; it should not retroactively rewrite the assessment.

I keep at least five dimensions separate:

Dimension Question
Risk / Priority How dangerous is this, and how urgently must we reduce exposure?
Engineering effort How much work does the permanent fix require?
Change / availability risk Could remediation break production, create regressions, or cause downtime?
Fix availability Is there a patch/upgrade/hotfix, or do we need our own redesign?
Time at risk How long has the asset already remained exposed?

That creates a much more honest decision model:

Low remediation effort High remediation effort / change risk
High risk / high priority Fix now. This is the ideal P0/P1 quick win. Contain now, engineer the permanent fix next. Remove exposure, disable the feature, reduce privilege, isolate, add a verified control, then patch or redesign safely.
Lower risk / lower priority Take the quick win when it is almost free and unlikely to create regression. Plan, temporarily accept, or redesign with an owner, rationale, expiry, and reopen triggers.

The dangerous anti-pattern sounds like this:

“Yes, it is a P0, but the patch is hard, so let’s call the finding Medium.”

No. If the risk is truly P0, it remains P0. The immediate response may simply be containment / mitigation rather than patch: break the attack path quickly while Engineering prepares a safe permanent fix.

The reverse matters too. An easy fix does not automatically become P0. It may be a great quick win, but remediation convenience is not a measure of risk.

If you can explain this distinction cleanly in a technical interview, congratulations — somewhere, spiritually, another 15% just appeared in your compensation negotiation. :)

A practical decision matrix

No single row makes the decision for you. The matrix exists to make reasoning visible — not to outsource judgment to colored cells.

I prefer transparent qualitative reasoning over spreadsheet numerology. A clear High because X, Y, and Z is often more useful than a mysterious 8.736 produced by a formula nobody remembers writing. Seriously, what the hell is 8.736 supposed to communicate to a human being? We are engineers, not numerology enthusiasts. Say what the risk is and why.

Signal Low Medium High Critical signal
Severity limited impact material impact major C/I/A RCE, auth bypass, systemic compromise
Exposure offline/local internal customer/partner reachable Internet unauthenticated
Reachability proven unreachable uncertain statically reachable input-to-sink / runtime confirmed
Exploit maturity theoretical PoC with constraints functional exploit KEV / active exploitation
Asset criticality disposable supporting internal important production IAM, CI/CD, secrets, control plane
Blast radius isolated one service several systems/data supply chain / cross-tenant / org-wide
Controls strong and verified partial weak absent/bypassable
Confidence weak evidence mixed strong multiple independent evidence sources

Then map to an operational class.

P0 / Critical

Typical profile:

  • Internet-facing or easy lateral reach;
  • pre-auth / unauthenticated;
  • vulnerable path is reachable;
  • KEV / active exploitation / reliable weaponized exploit;
  • crown-jewel asset;
  • large blast radius;
  • no effective controls.

Action: immediate containment, emergency remediation lane, incident-response assumptions where justified, credential rotation, IOC review.

P1 / High

  • exploit path is real;
  • asset is important;
  • exploitation is feasible;
  • impact is high;
  • but active exploitation is not confirmed or partial mitigation exists.

Action: expedited fix, short SLA, named owner, active tracking.

P2 / Medium

  • vulnerability is applicable;
  • exploitation requires authentication, configuration, or another prerequisite;
  • blast radius is limited;
  • controls are working.

Action: normal engineering cycle with a concrete date.

P3 / Low / Temporarily Accepted

  • component is present but affected function is unreachable with strong evidence;
  • feature is disabled;
  • required configuration does not exist;
  • exposure is minimal;
  • compensating controls are verified.

Action: documented exception/risk acceptance with owner, expiration, and reopen conditions.

A risk acceptance without an expiration date is not risk management. It is archiving a problem.

Where CVSS v4, EPSS, KEV, SSVC, and VEX fit — and how the hell do you remember all of this?

These signals do not compete. They answer different questions. And if you forget one acronym but remember what the other two mean, you are fine. Understanding beats acronym bingo. Nobody has banned cheat sheets. When I taught at university, I let students use their notes during exams — because memorization and understanding are not the same skill.

Framework / Signal Question it answers
CVSS-B How severe is the vulnerability technically, in isolation?
CVSS Threat metrics What is the current exploit-maturity/threat state?
CVSS Environmental How does this deployment/environment alter severity context?
EPSS What is the estimated probability of observed exploitation over the next 30 days?
CISA KEV Has exploitation in the wild been confirmed?
SSVC What response decision should we make through a decision tree?
VEX Is a specific product affected, and how do we communicate that status?

CISA’s SSVC is useful as a mindset because it focuses on a decision tree, not score worship. CISA’s model uses outcomes such as Track, Track*, Attend, and Act.

I am not suggesting every company copy SSVC exactly. The important idea is that the purpose of assessment is to make a response decision, not produce a pretty number.

Case 1: CVSS 9.8, but the attack path is not available

Consider this production platform. The architecture is intentionally anonymized; some details stay behind the NDA, but the reasoning is the part that matters:

                         Internet
                            |
                            v
                       [Cloud LB]
                            |
                            v
                     [Nginx Ingress]
                            |
                            v
                     [Istio Gateway]
                            |
                            v
                  +-------------------+
                  | orders-api Pod    |
                  | app + sidecar     |
                  +-------------------+
                     |            |
                     v            v
                [PostgreSQL]   [Kafka/MQ]

CI/CD:
Developer -> GitLab -> Jenkins -> Registry -> Kubernetes

SCA finds a vulnerable XML-parsing dependency with CVSS 9.8.

The dashboard turns red. The default SLA says “Critical.”

What an inexperienced engineer does

Creates a Jira ticket:

Upgrade immediately. CVSS 9.8.

Technically a ticket. Spiritually, an automated email with anxiety attached.

What a Senior Product Security Engineer does

Checks applicability and path evidence.

  1. The package is genuinely present in the runtime image.
  2. The affected function is used only by a legacy XML-import module.
  3. The xml_import=false feature flag is set in production.
  4. The import route is absent from Nginx/Istio configuration.
  5. Static call-graph analysis does not find a path from HTTP handlers to the affected parser.
  6. Runtime tracing does not show the parser loading during the observed period.
  7. NetworkPolicy is not the main justification, but it further limits lateral movement.
  8. No KEV or active-exploitation signal currently invalidates those assumptions.

Reachability verdict

Package present:        YES
Affected version:       YES
Imported:               YES
Affected function:      NOT REACHED by current static evidence
Published route:        NO
Feature enabled:        NO
Runtime observed path:  NO
Confidence:             MEDIUM-HIGH

Decision

Technical severity remains Critical. We are not arguing with the vulnerability; we are separating intrinsic severity from our current exposure and exploitability.

Operational priority may reasonably be P2, because the deployed product currently offers no attacker path to the affected function. But I would not close and forget.

I would:

  • upgrade the dependency in the next release train;
  • issue a VEX not_affected statement with a justification such as code_not_reachable, when supported by the VEX format in use;
  • retain the evidence;
  • assign an expiration date;
  • define automatic reopen triggers.

For example:

Reopen if:
- XML import feature is enabled;
- route is published;
- dependency behavior changes;
- reliable exploit changes assumptions;
- CVE enters KEV;
- architecture / call path changes.

Lesson: we did not “ignore a Critical.” We made a bounded, evidence-based exploitability conclusion with explicit confidence and reassessment conditions.

Case 2: no direct RCE, but priority becomes Critical

Now the opposite scenario. This one is worth remembering because it is exactly where “but it is not RCE” thinking gets expensive.

Internet
   |
   v
[CDN / WAF]
   |
   v
[Nginx Ingress]
   |
   v
[image-preview API]
   |
   |  outbound fetch
   v
[internal/cloud endpoints]
   |
   +--> metadata / workload identity (if reachable)
   +--> internal admin services
   +--> storage
   +--> registry

The preview function contains an SSRF weakness.

At first glance:

  • there is no direct RCE;
  • the endpoint “just downloads an image”;
  • the scanner might rate it Medium/High;
  • engineering wants to put it into the normal backlog.

Exposure

  • Internet-facing;
  • no account required;
  • requests are easy to automate.

Reachability

  • attacker controls the URL;
  • URL reaches the outbound HTTP client;
  • egress is unrestricted;
  • there is no destination allowlist.

Identity context

The workload has a cloud identity and can access internal resources.

Blast radius

A successful SSRF may become:

Internet actor
   -> SSRF primitive
   -> internal/cloud endpoint access
   -> credentials / internal service access
   -> data or registry compromise

Response

The code needs to be fixed, but fast containment may come first. This is where “just patch it” stops being strategy and starts being wishful thinking:

  • disable preview;
  • add an outbound allowlist;
  • block link-local/metadata destinations;
  • enforce egress NetworkPolicy;
  • reduce workload IAM;
  • move the fetcher into a more isolated workload;
  • add authentication/rate limiting where product design supports it;
  • then implement the permanent code fix.

Outcome

Technical severity:   Medium/High
Internet exposure:    Critical signal
Reachability:         Confirmed
Exploit automation:   High
Business impact:      High/Critical
Controls:             Weak
Priority:             P0/P1

Lesson: absence of RCE does not make a vulnerability low risk. In Product Security, exploit chains matter more than CWE labels.

Case 3: TeamCity CVE-2023-42793 — when nearly every signal points in the same direction

Now a real-world example. In 2023, JetBrains disclosed CVE-2023-42793 in TeamCity On-Premises. Google it if you want the ugly details. The vendor described a scenario in which an unauthenticated attacker with HTTP(S) access could achieve RCE and administrative control of the TeamCity server. JetBrains shipped a fix in 2023.05.4 and provided a security patch plugin for older versions. Nasty bug. Great case study. Probably considerably less fun if you were the team responsible for TeamCity that week.

JetBrains later reported observed exploitation, including nation-state activity. CISA added the vulnerability to KEV.

Imagine this enterprise deployment:

Internet / Corp Network
          |
          v
   [TeamCity Server]
          |
          +----> GitLab repos
          |
          +----> Build agents
          |
          +----> Docker Registry
          |
          +----> Artifact repository
          |
          +----> Kubernetes deploy token
          |
          +----> Cloud secrets / IAM

Contextual signals:

  • Severity: Critical;
  • Exposure: Critical if public, still material if internal;
  • Reachability: direct HTTP(S);
  • Auth requirement: pre-auth/unauthenticated in the vulnerable scenario;
  • Threat intelligence: active exploitation;
  • KEV: yes;
  • Asset criticality: CI/CD crown jewel;
  • Blast radius: source + artifacts + deployments + secrets;
  • Supply-chain impact: possible downstream compromise.

At that point, arguing whether the score should be 9.8 or 10.0 has roughly the same operational value as debating the font while the building alarm is going off.

Strong response

  1. Contain — remove public exposure or restrict access if patching is not immediate.
  2. Patch/upgrade — apply the vendor fix.
  3. Hunt — inspect IOCs, logs, and abnormal behavior.
  4. Assess secret exposure — determine which credentials were available to TeamCity.
  5. Rotate — deployment tokens, registry credentials, and cloud credentials where justified.
  6. Inspect downstream systems — build agents, artifacts, and releases.
  7. Restore — only after verification.

Lesson: mature vulnerability management sometimes has to transition directly into incident-response mode.

Three more real-world anchors

Jenkins CVE-2024-23897

Jenkins disclosed an arbitrary file-read issue through the CLI that could lead to more serious outcomes, including RCE scenarios under specific conditions. The vendor documented prerequisites and a workaround: disabling CLI access could prevent exploitation while teams prepared an upgrade.

What this teaches:

  • the label “file read” can understate downstream impact;
  • prerequisites matter;
  • configuration and runtime details can materially change exploitability;
  • temporary mitigation can be the correct first response while patching is underway.

XZ Utils CVE-2024-3094

The XZ backdoor illustrated another side of contextual analysis: a major industry event does not mean every Linux system is affected equally.

Teams had to determine:

  • exact version;
  • distro/build;
  • package provenance;
  • runtime interaction;
  • whether the malicious build existed on the system at all.

Red Hat, for example, separately documented affected Fedora builds and stated that RHEL was not affected.

Lesson: inventory, provenance, and applicability may matter more than headline severity.

HTTP/2 Rapid Reset CVE-2023-44487

For a public, high-volume edge service, an availability vulnerability can be P0 even without code execution or data theft.

Lesson: CIA impact must be evaluated against the business function. Availability can be the dominant risk dimension.

Compensating controls: never trust the architecture slide by itself

One of the most dangerous phrases in a triage meeting is:

“But we have a WAF.”

Cool. Show me the rule. Which exploit primitive does it block? Where is it enforced? Did we actually test a bypass? Is there an alternate route around it? A logo on the architecture slide is not a compensating control.

The same applies to:

  • NetworkPolicy;
  • service-mesh authorization;
  • VPN;
  • MFA;
  • EDR;
  • runtime protection;
  • least privilege;
  • egress deny;
  • secret isolation.

A compensating control should map to an attack path. Otherwise, sorry, that is not a control — that is security theater with better branding.

For example:

Attacker
   |
   v
[Ingress]
   |
   v
[API Pod]
   |
   +------X------> Metadata
          |
      egress deny
      VERIFIED

That control breaks a concrete edge in the attack graph.

“WAF enabled” without evidence does not.

What “influencing the decision” means for a Senior Engineer

When I say a security engineer should influence the decision, I do not mean Security should unilaterally decide whether a release ships. A healthy decision model looks like this.

Security brings

  • exploit mechanics;
  • reachability evidence;
  • threat intelligence;
  • likely attack path;
  • blast radius;
  • mitigation options;
  • residual risk.

Engineering brings

  • implementation reality;
  • release constraints;
  • regression risk;
  • patch complexity;
  • feature dependencies.

Product / Business Owner brings

  • customer impact;
  • contractual commitments;
  • revenue/availability context;
  • acceptable downtime;
  • risk tolerance.

Leadership makes or delegates the decision

  • fix now;
  • ship with mitigation;
  • disable feature;
  • roll back;
  • schedule emergency maintenance;
  • grant documented exception;
  • accept residual risk.

The Security Engineer is a decision enabler, not a person who merely generates red tickets. Yes, the engineer may sit lower on the org chart and get paid less than the Head — but without the engineer’s evidence, the “executive decision” is mostly just an expensive opinion.

Risk treatment: more options than “patch / do not patch”

NIST-style risk management commonly discusses strategies such as mitigate, avoid, transfer, and accept. In a vulnerability workflow, I translate that into engineering actions.

Treatment Example
Remediate upgrade or fix code
Mitigate WAF rule, egress block, auth requirement
Contain isolate host, remove Internet exposure
Avoid disable/remove vulnerable feature
Reduce privilege IAM/RBAC hardening, remove secrets
Detect temporary monitoring while patch is pending
Rollback return to known-good version
Rotate invalidate potentially exposed credentials
Accept temporarily documented exception with expiration
Redesign architecture change to eliminate the class of risk

The key principle: a mitigation should reduce either likelihood or impact. If it changes neither, it is not mitigation. It is comfort.

Who participates in a good assessment?

Strong triage is rarely a one-person activity. If one person is expected to know the code path, the cloud IAM graph, the business impact, the active threat picture, and every deployment detail from memory, you are probably either in a very small startup or in a process that still has some growing up to do.

Role What they usually know best
Product Security / AppSec vulnerability mechanics, code paths, abuse cases
Senior Developer implementation details, feature flags, actual call paths
Platform / Cloud Security IAM, network, Kubernetes, cloud controls
SRE / Infrastructure topology, deployment reality, operational impact
Service Owner customer and business criticality
Threat Intel / SOC exploitation activity, IOCs, campaigns
Security Lead risk appetite, exceptions, cross-team priority

Maturity is not Security pretending to know everything. That fantasy usually lasts until the first weird legacy service appears. Maturity is having a process that quickly gets the right context from the right owner, discusses the evidence together, turns the decision into an action plan, and pushes the work to the right layers — Security, Dev, Ops, QA, whoever actually owns the next move. That is much healthier than turning triage into a three-week archaeological expedition.

Three levels of thinking: Junior, Senior, Lead

If you are a Junior Engineer or candidate

Your first goal is to stop treating scanner output as truth. The scanner is a witness, not the judge.

Minimum workflow:

  1. understand the CVE/CWE;
  2. identify affected version;
  3. identify the asset;
  4. check exposure;
  5. understand auth/prerequisites;
  6. check PoC/KEV/EPSS;
  7. talk to a developer about the code path;
  8. describe impact;
  9. propose remediation plus mitigation.

If you can do this, you already think more like a Product Security Engineer than someone whose vulnerability strategy is basically ORDER BY cvss DESC.

If you are a Senior Engineer

You are expected to provide:

  • triage ownership;
  • attack-path reasoning;
  • confidence-aware conclusions;
  • strong communication with dev/platform teams;
  • business translation;
  • viable treatment options;
  • verification after remediation;
  • disciplined exception handling.

A Senior does not just say “this is bad.” Everybody in the room can see the red icon. A Senior says:

“Here is the path, here is the evidence, here is the impact, here are three ways to reduce the risk, here is the fastest one, and here is the residual risk.”

If you are a Technical Lead or Security Lead

Now the problem is bigger than one finding. Heroics do not scale, and neither does one heroic engineer manually interpreting 20,000 scanner rows forever.

You need a system:

  • common triage rubric;
  • risk taxonomy;
  • ownership model;
  • SLAs;
  • exception workflow;
  • KEV/EPSS enrichment;
  • SBOM/VEX integration;
  • duplicate suppression;
  • reopen triggers;
  • quality metrics.

Useful lead-level metrics:

  • MTTR by risk class, not CVSS alone;
  • age of reachable Critical/High findings;
  • KEV exposure time;
  • Internet-exposed exploitable findings;
  • expired exceptions;
  • percentage of findings with an accountable owner;
  • false-positive and duplicate rate;
  • percentage of SCA findings with reachability evidence;
  • time from finding to containment;
  • recurrence rate by CWE/root cause.

That is vulnerability management as an engineering system, not a spreadsheet with conditional formatting and hopes. At Lead level there is usually a little less “which flag does the scanner use?” and a lot more outcomes, ownership, trade-offs, and system design.

What I want a new engineer to remember

When you receive your next finding, resist the ancient security ritual of immediately calling it “Critical” and opening an emergency Slack channel.

Walk through this checklist:

[ ] Is it real?
[ ] Are we affected?
[ ] Where is it deployed?
[ ] Who can reach it?
[ ] Can input reach the vulnerable sink?
[ ] Is there a PoC / EPSS / KEV signal?
[ ] What identity/privileges does the workload have?
[ ] What can the attacker reach next?
[ ] What is the business impact?
[ ] Which controls actually break the path?
[ ] What is the fastest safe treatment?
[ ] Who owns it and when do we reassess?

If you can answer those questions, you have the basis for a defensible risk decision. If you cannot, that is not failure — it means keep digging, ask somebody who knows the system, gather more evidence, and keep building the professional skill. Unknown is a valid engineering state. Pretending is not.

Interview-ready answer: “How do you prioritize vulnerabilities?”

A strong concise Product Security answer sounds like this:

“I do not use CVSS as the only priority signal. I first confirm applicability and deployment context, then evaluate exposure and reachability to the vulnerable function. After that I add exploit intelligence such as EPSS, CISA KEV, public PoCs, and active exploitation. I then assess asset criticality, runtime identity, blast radius, and business impact, verify compensating controls, and only then assign remediation priority. My goal is to build the attack path and choose the response that reduces residual risk fastest: patching, isolation, feature disablement, IAM reduction, or a temporary documented exception.”

When a candidate answers like that, I know they are thinking in terms of a risk system, not just reciting scanner vocabulary from a cheat sheet. That is at least solid Mid-level thinking, and often Mid+/Senior depending on the depth. More skill → more expertise → more responsibility → and, ideally, more money. Funny how that chain works. :)

What should be automated, and what still needs a human?

Automation — AI included — is great at:

  • inventory;
  • SCA/CVE matching;
  • CVSS enrichment;
  • EPSS;
  • KEV flags;
  • Internet-exposure signals;
  • cloud asset metadata;
  • basic reachability;
  • duplicate correlation;
  • SLA routing.

Humans are still needed for:

  • business impact;
  • weird architecture;
  • dynamic code paths;
  • exploit-chain reasoning;
  • control validation;
  • exception justification;
  • delivery-vs-risk tradeoffs;
  • assessment confidence.

This is why ASPM, CNAPP, and SCA platforms keep moving toward context correlation. That is useful. The part where a vendor dashboard claims to have compressed your entire architecture, business model, IAM graph, customer impact, and threat environment into one magic number? Treat that part with healthy suspicion.

Common mistakes I wish new engineers could skip

Mistake 1. CVSS equals risk

It does not. CVSS is a severity input. The number is useful; the worship is optional.

Mistake 2. Package present equals vulnerable path reachable

It does not. An SBOM is not a confession. You still need applicability and reachability analysis.

Mistake 3. Internal equals safe

It does not. “Internal” has protected many terrible assumptions over the years. An internal crown jewel can be more dangerous than an edge service.

Mistake 4. We have a WAF, therefore mitigated

Only if a concrete rule actually breaks the exploit primitive. Otherwise you have a WAF and a vulnerability.

Mistake 5. No public PoC means no urgency

Wrong. Attackers are not required to publish a GitHub repo before exploiting you. A PoC is only one threat signal.

Mistake 6. Patch deployed means ticket closed

Not yet. kubectl rollout status is comforting, but verify version, artifact, path, and behavior.

Mistake 7. Accepted risk means accepted forever

No. “Accepted forever” is usually just “forgotten with paperwork.” You need an owner, expiration, and reopen triggers.

Mistake 8. Security must always demand a code fix

No. Security is not paid by the number of BLOCKED comments it leaves in Jira. It should help the organization make the right risk decision.

A lightweight model for teams starting from scratch

If I were building this process in a new organization, I would not start by inventing a twelve-factor scoring engine with color gradients and a steering committee. I would start with five mandatory fields:

1. Exposure
2. Reachability
3. Exploit status
4. Asset/business criticality
5. Verified controls

Then add one meta-field:

Assessment Confidence: Low / Medium / High

Why does confidence matter?

Because these are not the same statement:

"Not reachable, confidence HIGH"

and

"Not reachable because the scanner didn't find anything, confidence LOW"

A decision should capture not only the conclusion, but how strongly the evidence supports it.

Final model

This is how I visualize modern vulnerability triage:

                    +----------------------+
                    | Finding / CVE / CWE  |
                    +----------+-----------+
                               |
                               v
                    +----------------------+
                    | Applicability        |
                    | version/build/runtime|
                    +----------+-----------+
                               |
                               v
                    +----------------------+
                    | Exposure             |
                    | Internet/Auth/Trust  |
                    +----------+-----------+
                               |
                               v
                    +----------------------+
                    | Reachability         |
                    | route/call/taint     |
                    +----------+-----------+
                               |
                               v
                    +----------------------+
                    | Exploitability       |
                    | CVSS/EPSS/KEV/PoC    |
                    +----------+-----------+
                               |
                               v
                    +----------------------+
                    | Identity + Blast     |
                    | Radius + Crown Jewels|
                    +----------+-----------+
                               |
                               v
                    +----------------------+
                    | Business Impact      |
                    +----------+-----------+
                               |
                               v
                    +----------------------+
                    | Verified Controls    |
                    +----------+-----------+
                               |
                               v
                    +----------------------+
                    | Risk / Priority      |
                    | P0 / P1 / P2 / P3    |
                    +----------+-----------+
                               |
                               v
                    +----------------------+
                    | Treatment            |
                    | Fix/Mitigate/Accept  |
                    +----------+-----------+
                               |
                               v
                    +----------------------+
                    | Verify + Reassess    |
                    +----------------------+

CVSS remains useful. It just no longer sits on the throne. No coup required. It belongs where it should have been all along: one signal feeding an engineering decision system.

The takeaway

When I worked as an engineer, my job was not simply to find a vulnerability, paint it red, and hand the anxiety to someone else. My job was to make the problem understandable and help the team make the right decision.

Sometimes the right decision is an emergency patch.
Sometimes it is disabling a feature in 15 minutes and patching tomorrow.
Sometimes it is removing an Internet route.
Sometimes it is reducing IAM privileges and breaking the exploit chain.
Sometimes it is documenting that vulnerable code is genuinely unreachable in your product and upgrading the dependency in the next release.

But every one of those decisions should be based on evidence, not vibes — even if the vibes are very red and come from an expensive dashboard.

Do not ask only, “What is the CVSS score?”

Ask: “Does this apply to us? Can the attacker reach the vulnerable path? How likely is exploitation? What do they gain after the first step? What is the blast radius? What does the business lose? And what is the fastest way to break the attack path?”

That is the point where vulnerability management stops being a queue of red rows in a dashboard and becomes a real Product Security engineering discipline. Same finding, different context, completely different decision — and that is exactly why the human judgment still matters.

Free toolbox: where I look during vulnerability triage

I do not open twenty browser tabs just to feel productive. These are the free sources I actually reach for when I need to answer a vulnerability-triage question fast.

No external portal knows your architecture, identities, trust boundaries, or business impact. If a website claims it does, congratulations: you have found marketing. But a small set of free resources can close a large part of the fact-finding gap very quickly.

Resource What I would use it for Keep in mind
FIRST EPSS Probability + percentile, history, API, and a daily CSV. Excellent enrichment for a large backlog. It forecasts exploitation activity; it is not your complete risk score.
CISA KEV Quickly check whether exploitation in the wild has been confirmed. KEV is a strong threat signal, but you still need to confirm applicability to your product.
Rapid7 Vulnerability & Exploit Database A useful visual CVE browser with CVSS v3/v4, EPSS, Exploited in the Wild, Metasploit-module availability, and emergent-threat research. Great for a fast analyst view; verify critical decisions against vendor advisories and your own environment.
OSV.dev + OSV-Scanner Open-source dependencies, lockfiles/SBOM/container images, fixed versions, HTML/JSON/SARIF, plus call analysis for supported languages. called=false or a missing discovered path is evidence, not absolute proof of safety. Dynamic loading and reflection still matter.
ProjectDiscovery CVEMap Fast CLI enrichment around CVSS, EPSS, KEV, PoCs, Nuclei coverage, vulnerability age, and filtering; useful for shell/JSON automation. It is an aggregator. For a critical decision, verify primary sources and the vendor advisory.

I still keep NVD nearby as a useful baseline for CVE/CVSS/CWE/CPE data and references. NVD itself explicitly notes that CVSS measures severity, not risk.

Zero-budget triage in Excel / Google Sheets

If you do not have an ASPM or vulnerability-management platform yet, that is not an excuse to manage risk by telepathy. You can build a surprisingly useful workflow from CSV exports and a few enrichment sources.

  1. Export findings from your SCA/VM/scanner to CSV.
  2. Enrich each CVE with EPSS probability + percentile from the FIRST API/CSV.
  3. Add a KEV flag.
  4. Fill local context manually or from your asset inventory.
  5. Filter and prioritize the backlog using more than CVSS.

A practical column set is:

CVE / Finding ID
Asset / Service
Environment
Owner
CVSS + Vector
EPSS Probability
EPSS Percentile
EPSS Checked At
KEV Y/N
Public PoC / Exploit Y/N
Internet Exposure
Authentication Required
Reachability
Reachability Evidence
Runtime Identity / Privileges
Asset Criticality
Blast Radius
Business Impact
Compensating Controls
Assessment Confidence
Risk Priority
Remediation Effort
Change Risk
Treatment
SLA / Due Date
Exception Expiry
Reopen Triggers

FIRST publishes EPSS through an API and a daily CSV, so it is easy to JOIN the data by CVE even without commercial tooling. The important part is not to turn the spreadsheet into a homegrown Bloomberg terminal for vulnerabilities. The sheet should preserve evidence and support a decision, not hide reasoning behind an opaque score. Same data, more context, better decisions — that is the whole game.

References and further reading

  1. FIRST — CVSS v4.0 User Guide https://www.first.org/cvss/v4.0/user-guide
  2. FIRST — CVSS v4.0 Specification https://www.first.org/cvss/v4.0/specification-document
  3. FIRST — Exploit Prediction Scoring System (EPSS) https://www.first.org/epss/
  4. FIRST — EPSS FAQ https://www.first.org/epss/faq
  5. CISA — Known Exploited Vulnerabilities Catalog https://www.cisa.gov/known-exploited-vulnerabilities-catalog
  6. CISA — Stakeholder-Specific Vulnerability Categorization (SSVC) https://www.cisa.gov/stakeholder-specific-vulnerability-categorization-ssvc
  7. CISA — SBOM / VEX Resources Library https://www.cisa.gov/topics/cyber-threats-and-advisories/sbom/sbomresourceslibrary
  8. CycloneDX — Vulnerability Exploitability eXchange (VEX) https://cyclonedx.org/capabilities/vex/
  9. NIST SP 800-40 Rev. 4 — Guide to Enterprise Patch Management Planning https://csrc.nist.gov/pubs/sp/800/40/r4/final
  10. NIST IR 8179 — Criticality Analysis Process Model https://csrc.nist.gov/pubs/ir/8179/final
  11. NIST IR 8286B — Prioritizing Cybersecurity Risk for Enterprise Risk Management https://www.nist.gov/publications/prioritizing-cybersecurity-risk-enterprise-risk-management-0
  12. OWASP — Risk Rating Methodology https://owasp.org/www-community/OWASP_Risk_Rating_Methodology
  13. OWASP — Vulnerable Dependency Management Cheat Sheet https://cheatsheetseries.owasp.org/cheatsheets/Vulnerable_Dependency_Management_Cheat_Sheet.html
  14. Google — OSV-Scanner Call Analysis https://google.github.io/osv-scanner/output/
  15. OWASP dep-scan — Reachability-aware dependency analysis https://github.com/owasp-dep-scan/dep-scan
  16. JetBrains — CVE-2023-42793 TeamCity security issue https://blog.jetbrains.com/teamcity/2023/09/critical-security-issue-affecting-teamcity-on-premises-update-to-2023-05-4-now/
  17. JetBrains — CVE-2023-42793 exploitation update https://blog.jetbrains.com/teamcity/2023/10/cve-2023-42793-vulnerability-in-teamcity-october-18-2023-update/
  18. Jenkins — Security Advisory 2024-01-24 / CVE-2024-23897 https://www.jenkins.io/security/advisory/2024-01-24/
  19. Red Hat — CVE-2024-3094 / XZ Utils alert https://www.redhat.com/en/blog/urgent-security-alert-fedora-40-and-rawhide-users
  20. FIRST — EPSS Get the Data (API + daily CSV) https://www.first.org/epss/data
  21. Rapid7 — Vulnerability & Exploit Database https://www.rapid7.com/db/
  22. ProjectDiscovery — CVEMap https://github.com/projectdiscovery/cvemap
  23. NIST — National Vulnerability Database (NVD) https://nvd.nist.gov/

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.