CVSS Scores Explained: How Vulnerability Severity Is Really Calculated
Every vulnerability report shows CVSS numbers, but most teams read them wrong. Here's how CVSS v3.1 scores are actually computed, what each metric means, and how to prioritize.
Every vulnerability scanner in the world prints a number between 0.0 and 10.0 next to each finding, and every organization runs its remediation SLAs off those numbers: "critical within 7 days, high within 30," and so on. Yet in our experience reviewing thousands of scan reports, most teams cannot say what the number actually measures — and the misunderstandings lead to real prioritization mistakes, in both directions. This guide explains how CVSS v3.1 really works, what each part of the vector string means, and how to read severity scores the way a vulnerability manager should.
What CVSS Actually Measures
CVSS (the Common Vulnerability Scoring System, maintained by FIRST.org) computes a base score that answers one narrow question: how severe is this vulnerability in isolation, under the worst plausible circumstances for the affected component?
It deliberately does not measure:
- whether the vulnerable component is exposed on your network (that's the environmental layer)
- whether a working exploit exists in the wild right now (that's threat intelligence — CVSS's companion metrics, not the base score)
- how important the affected system is to your business
That is why a 9.8 on an internal, firewalled admin tool and a 9.8 on your public checkout page carry the same number and radically different urgency. The base score is a severity component, not a risk verdict.
The Eight Base Metrics
A CVSS v3.1 base score is computed from eight metrics, each visible in the vector string — for example CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (the classic 9.8):
Exploitability metrics (how hard is it to pull off?)
- AV — Attack Vector: Network (N), Adjacent (A), Local (L), or Physical (P). Network means the attacker needs no prior access to your environment — the scariest setting.
- AC — Attack Complexity: Low or High. High means success depends on conditions the attacker cannot fully control (a race, a specific configuration).
- PR — Privileges Required: None, Low, or High. None means any internet stranger can attempt it.
- UI — User Interaction: None or Required. Required means a victim has to click something (phishing-dependent bugs are less reliably exploitable).
Scope (does it escape the component?)
- S — Scope: Changed or Unchanged. If exploiting the vulnerability lets the attacker affect a component beyond the vulnerable one (say, a web app bug that compromises the underlying server), scope is Changed — and the score formula multiplies impact accordingly.
Impact metrics (what does the attacker get?)
- C — Confidentiality: None, Low, or High — data disclosure
- I — Integrity: None, Low, or High — data modification
- A — Availability: None, Low, or High — service disruption
How the Number Is Computed (the Part Nobody Reads)
The calculation, per the official CVSS v3.1 specification, works like this:
- Impact subscore — a formula over C/I/A that saturates: the first High impact matters enormously; stacking all three Highs does not triple the impact. Scope-Changed multiplies the impact contribution by 1.08 (the escalation beyond the component boundary is priced in).
- Exploitability subscore — 8.22 × AV × AC × PR × UI, where each metric contributes a multiplier (AV:N is 0.85, PR:N is 0.85, and so on).
- Base score = Roundup(minimum(Impact + Exploitability, 10)) — when Impact is nonzero; zero impact means zero score regardless of how trivially exploitable the bug is.
The Roundup function deserves special mention because it is where naive implementations go wrong: scores are rounded up to one decimal place using integer arithmetic (multiply by 10, ceiling, divide by 10) — not standard floating-point rounding. It is a small detail; it is also the difference between matching FIRST's published scores and being off by 0.1 on a decent fraction of vulnerabilities. (We compute scores locally, exactly per the specification, including the Roundup rule and the scope multiplier — precisely so our reports match the official calculator, because a score a client cannot reproduce is a score they cannot trust.)
Reading the Severity Bands
| Score | Severity | Typical reading |
|---|---|---|
| 9.0–10.0 | Critical | Exploitable with no privileges, no interaction, major impact — fix first |
| 7.0–8.9 | High | Serious impact or trivially exploitable — schedule immediately |
| 4.0–6.9 | Medium | Meaningful but constrained — plan within the month |
| 0.1–3.9 | Low | Hardening-grade findings — backlog |
The Mistakes to Avoid
Mistake 1: sorting purely by score. A 7.5 on your internet-facing login page outranks a 9.1 on a tool behind VPN. Base scores rank vulnerabilities; you need to rank your vulnerabilities — with exposure in mind.
Mistake 2: ignoring the vector. Two 8.8s can be different problems: one needs valid credentials (PR:L), one does not (PR:N). The vector string is where the operational meaning lives.
Mistake 3: treating "no score" as "no problem." Missing security headers, verbose errors, and information disclosure findings are often hardening issues without CVSS vectors. They still matter — as hardening, not as emergencies. A good report separates the two registers instead of inflating everything to critical.
Mistake 4: expecting the score to track the news. A 5.3 that's being mass-exploited in the wild deserves more urgency than a quiet 8.1. Severity (CVSS) and threat (KEV lists, EPSS, exploit chatter) are different axes — the mature approach uses both.
How Our Reports Use CVSS
Every finding in a 2MNY report carries its CVSS v3.1 base score, the full vector string, and the evidence behind the severity — computed locally from the specification, never estimated. Findings without vectors (hardening-class issues) are labeled as such with honest severity ratings, so your team can trust that "critical" always means critical. The goal is a report you can hand to engineers and management without translation.
See It in Action
Run a free scan on a site you own and read a real report with CVSS-scored findings. The features page lists the full 232-scanner engine, and the open-source core (200 modules, Apache-2.0) is on GitHub for self-hosting.
Related reading: Supply-Chain Dependency Vulnerabilities · What Is SQL Injection? · Open-Source Web Vulnerability Scanners in 2026
1 What is a CVSS score?
CVSS (Common Vulnerability Scoring System) turns a vulnerability's technical characteristics into a 0-10 severity number, computed from metrics like attack complexity, required privileges, user interaction, and impact on confidentiality, integrity, and availability. It gives everyone — scanners, vendors, auditors — a shared severity language.
2 What do the CVSS severity levels mean?
The bands are: 0.0 None, 0.1-3.9 Low, 4.0-6.9 Medium, 7.0-8.9 High, and 9.0-10.0 Critical. A 9.8 SQL injection exposing your database is not "a bit worse" than a 5.3 header misconfiguration — it is a different class of urgency. Every 2MNY finding carries its CVSS score, vector string, and the reasoning behind it.
3 Why does the same vulnerability get different scores from different tools?
Because some metrics are contextual: the base score is standardized, but tools differ on whether the affected host is internet-exposed, whether authentication is required in your deployment, and which version of CVSS (3.1 vs 4.0) they apply. Demanding the vector string — not just the number — lets you compare scores honestly.
4 Is a high CVSS score always urgent?
Not automatically — CVSS measures technical severity, not exploitability in your context. A 9.8 in an internal, isolated service behind VPN is less urgent than a 7.5 that is actively exploited in the wild. That is why 2MNY enriches every finding with EPSS probability and CISA KEV status for real-world prioritization.