From Severity to Fix Order
A CVSS base score says how bad exploitation would be, anywhere. Choosing what to fix first also needs likelihood now and what the system holds: the temporal and environmental scores [1].
1. Severity is not risk
Risk is roughly likelihood × impact. The base score is a severity: it assumes the attack happens and rates the damage. Two equal base scores can differ in risk: one vulnerability has a public exploit on an internet-facing payment server, the other none on an internal demo. The temporal score adjusts for likelihood, the environmental score for what is at stake; fix order follows them, not the base score alone.
2. Temporal score
The temporal score is roundup(Base × E × RL × RC), with the weights below, paraphrased from the 3.1 specification [1]. Each metric also has X (Not Defined) [1], scored like the highest value.
| Metric | Choose this value when… |
|---|---|
| Exploit Code Maturity (E) | H [1]: autonomous exploit code (a worm, a point-and-click tool), or none needed and details public · F [0.97]: functional exploit code works in most situations · P [0.94]: only proof-of-concept code, which a skilled attacker must adapt · U [0.91]: no exploit code, or the attack is theoretical |
| Remediation Level (RL) | U [1]: no fix, or none that can be applied · W [0.97]: an unofficial, non-vendor workaround · T [0.96]: an official but temporary fix, such as a vendor hotfix · O [0.95]: a complete vendor fix, a patch or an upgrade |
| Report Confidence (RC) | C [1]: confirmed, by the vendor, the source code or a working reproduction · R [0.96]: details public, root cause not fully confirmed · U [0.92]: impact reported, cause unknown or disputed |
E, RL and RC describe a published vulnerability’s exploit and fix status, so temporal scoring applies to published CVEs.
Example: Log4Shell at CVE publication. NVD published CVE-2021-44228 on 10 December 2021 with base 10.0 [2], and the official fix, 2.15.0, was out that day [3]: RL:O. Exploiting it needed only a one-line string in any logged field, with no tooling, and mass attempts followed within hours; Cloudflare saw the first nine minutes after disclosure and probes from 1 December [4]. That is “no exploit required, details widely available”: E:H. The vendor confirmed it: RC:C. Temporal = 10.0 × 1 × 0.95 × 1 = 9.5. The fix later proved incomplete (CVE-2021-45046; 2.16.0 replaced it) [5], so a remediation level is a snapshot.
3. Environmental score
The environmental score recomputes the base score with the organisation’s Confidentiality, Integrity and Availability Requirements (CR, IR, AR: Low 0.5 · Medium 1 · High 1.5) and, optionally, modified base metrics (MAV, MAC, MPR, MUI, MC, MI, MA), which restate a base metric for one deployment. With scope unchanged, the specification caps MISS at 0.915:
| Requirement (CR, IR, AR) | Low [0.5] | Medium [1] | High [1.5] |
|---|---|---|---|
| Loss of C, I or A would have… | a limited adverse effect | a serious adverse effect | a catastrophic adverse effect |
Modified Exploitability = 8.22 × MAV × MAC × MPR × MUI, the base exploitability with any modified values put in. The environmental score is roundup(roundup(min(Modified Impact + Modified Exploitability, 10)) × the three temporal weights). With scope changed (not needed for the shop) it follows the base pattern: Modified Impact = 7.52 × (MISS − 0.029) − 3.25 × (MISS × 0.9731 − 0.02)^13 (as the 3.1 specification states), and the sum is multiplied by 1.08 before the cap. A requirement left Not Defined (X) counts as 1, the same as Medium, whereas a temporal X counts as the highest value; a modified base metric left X keeps its base value.
Example (a hypothetical demo shop). The shop’s SQL injection, AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N, base 9.1, no temporal metrics (weights 1). A demo shop whose user table holds only nicknames sets CR:L, with IR and AR Medium (1): MISS = 1 − (1 − 0.5 × 0.56)(1 − 1 × 0.56)(1 − 1 × 0) = 0.6832, Modified Impact = 4.386, and roundup(min(4.386 + 3.887, 10)) = roundup(8.273) = 8.3, High rather than Critical. The full vector is AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N/CR:L/IR:M/AR:M.
Where the inputs come from on a real system. Temporal values change with the outside world: the vendor advisory gives remediation level and confirmation; exploit status comes from public exploit databases and CISA’s Known Exploited Vulnerabilities catalogue. CR, IR and AR come from the organisation’s data classification, set once per system, not per finding.
4. Example: ranking the shop’s findings
The Bandit findings from Static Security Analysis. Two are reachable vulnerabilities and get a score; neither reaches another system, so S:U:
| Finding | Who can reach it | Base = temporal (E, RL, RC = X, unpublished) | Environmental (CR:M/IR:M/AR:M) |
|---|---|---|---|
| SQL injection in login | anyone, through the login form | 9.1 | 9.1 |
eval of the discount code | any logged-in customer at checkout (PR:L) | 8.8 | 8.8 |
Two findings are not scored, because the vulnerability they enable depends on events outside the code shown. The hardcoded password (B105), the shop’s SECRET_KEY, is never used in that code, and its impact depends on how the key leaks and what it signs. Unsalted MD5 (B324) only raises the impact of another breach that leaks the user table, since cracked passwords are reused elsewhere.
The order. All findings go into one list sorted by score: the environmental score when requirements are set (it already includes the temporal weights), otherwise temporal for published CVEs and base for in-house findings; ties are broken by exposure (who can reach it now); unscored hardening items (changes that remove a weakness before any attack uses it) come last, ordered by who can reach them. Here: the injection (9.1, anyone), then eval (8.8). Then the key, moved out of the code and rotated, before MD5, because the key is exposed to anyone who reads the source while MD5 matters only after another breach; both are hardening, fixed after the scored findings.
When to use it — and when not
Use these scores to order fixes inside one organisation; a vendor advisory states only the base score.
Limitation
Both adjustments are coarse. Temporal weights lower a score by at most a fifth (0.91 × 0.95 × 0.92 = 0.80), and CVSS 3.1 does not measure whether attackers actually target a vulnerability.
How solid is this?
- Where it comes from. The weights and equations are from the 3.1 specification [1]; every score was recomputed from its vector.
- What is contested. How far an organisation’s requirements should outweigh the vendor’s base score.
- What we do not hold. Data comparing CVSS-ordered patching with other orderings in real organisations.
References
- Forum of Incident Response and Security Teams,“Common Vulnerability Scoring System v3.1: Specification Document.” 2019. [Online]. Available: https://www.first.org/cvss/specification-document
- National Institute of Standards and Technology,“CVE-2021-44228: Apache Log4j Remote Code Execution (Log4Shell).” 2021. [Online]. Available: https://nvd.nist.gov/vuln/detail/CVE-2021-44228
- CISA,“Apache Releases Log4j Version 2.15.0 to Address Critical RCE Vulnerability Under Exploitation.” Dec. 2021. [Online]. Available: https://www.cisa.gov/news-events/alerts/2021/12/10/apache-releases-log4j-version-2150-address-critical-rce-vulnerability-under-exploitation
- C. Martinho,“Exploitation of Log4j CVE-2021-44228 before public disclosure and evolution of evasion and exfiltration.” Dec. 2021. [Online]. Available: https://blog.cloudflare.com/exploitation-of-cve-2021-44228-before-public-disclosure-and-evolution-of-waf-evasion-patterns/
- Apache Logging Services,“Apache Log4j Security Vulnerabilities.” 2021. [Online]. Available: https://logging.apache.org/log4j/2.x/security.html
Disclaimer: AI is used for text summarization, polishing and explaining. Authors have verified all facts and claims. In case of an error, feel free to file an issue.