CyberNugget

L02 · Threats, Vulnerabilities, and Risk

Module 1: Security Foundations · ~20 min · Lesson 2 of 71

🎯 What you'll learn

  • What assets, threats, vulnerabilities, and exploits are, and how they chain together
  • Why risk = likelihood × impact, and how to use it to decide what to fix first
  • What CVE and CVSS are, and how to read a CVSS vector string field by field

🔥 Why this matters

In March 2017, Apache published a fix for a critical flaw in the Struts web framework (CVE-2017-5638). About two months later, attackers used that exact flaw to get into Equifax and took data on about 147 million people. The flaw was public and the patch was free, but the risk wasn't handled. (Full case study: L06.) This lesson is about the gap between "a vulnerability exists" and "this is a risk we must act on today".

1. Four words people mix up

Start with a house. You keep jewelry inside. Burglars work your street. Your back window doesn't latch. A burglar knows how to pop that latch with a credit card. Each of those has a security name:

  • An asset is anything of value you need to protect: data, systems, money, credentials, reputation.
  • A threat is anything that could harm an asset. When it's a person or group, it's a threat actor: a criminal gang, an insider, a bot scanning the internet. Threats can also be accidents, like a bad deploy.
  • A vulnerability is a weakness a threat could use: a bug, a misconfiguration, a missing check.
  • An exploit is the specific code or technique that takes advantage of a vulnerability.
 THREAT ACTOR      uses an     through a         to harm an
 (who or what) ──▶ EXPLOIT ──▶ VULNERABILITY ──▶ ASSET
 e.g. a botnet     (the how)   (the weakness)    (what you value)
 scanning the      crafted     log4j 2.14 in     policy data,
 internet          log string  policy-service    AWS credentials
                                                   │
                                                   │ result
                                                   ▼
                                                IMPACT
                                           (C, I, or A lost)

A risk needs all three: an asset worth harming, a threat able to harm it, and a vulnerability that lets the threat through. Remove one and that path carries no risk. A critical bug in a service that holds nothing and that nobody can reach is a vulnerability, but barely a risk.

Two more terms: a zero-day is a vulnerability exploited before the vendor has a fix, and a control is anything that reduces risk, such as a patch, an authorization check, or an alert.

2. Risk = likelihood × impact

Your team has 40 open security findings and one sprint. Which first? To compare them you need risk: the chance of something bad happening, combined with how bad it would be.

  • Likelihood is how probable it is that a threat exploits this weakness in a given period. It depends on exposure, how easy the attack is, and whether attackers already have or use an exploit.
  • Impact is how much harm results: which CIA goal fails, for how much data and money, and which regulator gets involved. (L01's FIPS 199 ratings are impact ratings.)
                        IMPACT ──▶
                 Low          Medium         High
           ┌─────────────┬─────────────┬─────────────┐
     High  │   MEDIUM    │    HIGH     │  CRITICAL   │
  L        ├─────────────┼─────────────┼─────────────┤
  I  Med   │    LOW      │   MEDIUM    │    HIGH     │
  K        ├─────────────┼─────────────┼─────────────┤
     Low   │    LOW      │    LOW      │   MEDIUM    │
           └─────────────┴─────────────┴─────────────┘
   fix order: top-right first, bottom-left maybe never

Most teams score each side from 1 to 5 and multiply, so 4 × 5 = 20 outranks 5 × 2 = 10. Treat the result as a sorting tool, not a measurement: multiplying two opinions isn't real arithmetic. The second deep dive shows a money-based version.

Controls work on one side or the other. A patch or an authorization check lowers likelihood. Encrypting fields or limiting what a token can read lowers impact. Whatever is left after your controls is residual risk.

3. CVE and CVSS: the public vocabulary

When a flaw is found in widely used software, everyone needs one name for it. That's CVE (Common Vulnerabilities and Exposures): a public catalog where each vulnerability gets an ID like CVE-2021-44228 (year plus sequence number). The program started in 1999 and is run by MITRE with US government (CISA) funding. IDs are issued by hundreds of CNAs (CVE Numbering Authorities), such as Apache, Microsoft, and GitHub.

A CVE ID says what the flaw is, not how bad. For that there's CVSS (Common Vulnerability Scoring System), a standard from the industry body FIRST that rates severity from 0.0 to 10.0. The NVD (National Vulnerability Database, run by NIST) adds CVSS scores and affected versions to each CVE.

Score Severity
0.0 None
0.1–3.9 Low
4.0–6.9 Medium
7.0–8.9 High
9.0–10.0 Critical

The score is calculated from a vector string, a compact code recording the answer to each question CVSS asks. You'll see vectors in scanner output and Dependabot alerts. Most tools still show version 3.1 (2019). CVSS v4.0, released by FIRST in November 2023, drops the Scope metric, adds Attack Requirements, and splits impact between the vulnerable system and other systems. Expect to see both for years.

One warning: the CVSS base score describes the vulnerability in general, the same for everyone. It doesn't know whether you run that library, whether it's reachable, or what data sits behind it. CVSS measures severity; risk is yours to work out. (CVSS has optional environmental metrics, but most tools show only the base score.)

🧪 Worked example

Part 1: reading Log4Shell's vector, field by field

Log4Shell (CVE-2021-44228), disclosed in December 2021, was a flaw in the Java logging library log4j 2. Logging an attacker-controlled string, such as a crafted User-Agent header, could make it fetch and run the attacker's code (details in L36). NVD's vector:

 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
 └──┬───┘ └────────┬────────┘ └┬┘ └────┬────┘
    │              │           │       │
 version    EXPLOITABILITY   SCOPE  IMPACT
            "how easy is it         "how bad if
             to pull off?"           it works?"
Field Value What it means here
AV, Attack Vector N = Network Exploitable remotely (others: Adjacent, Local, Physical)
AC, Attack Complexity L = Low No special conditions; works reliably
PR, Privileges Required N = None No account needed
UI, User Interaction N = None Nobody has to click anything
S, Scope C = Changed The flaw is in a library, but the damage reaches the whole app and host
C, Confidentiality H = High Read anything the process can: data, env vars, cloud credentials
I, Integrity H = High Change data and code
A, Availability H = High Crash or wipe the service

In one sentence: anyone on the internet, with no account and no help from a user, can reliably take full control of the application. That's why it scored the maximum, 10.0 Critical. Compare CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U/C:L/I:N/A:N: a local, hard-to-trigger, admin-only, minor information leak. It scores 1.9 Low.

Part 2: a small risk register for an API service

Now a made-up service: policy-api at api.example.com, behind Kong on EKS, storing policies in MongoDB. A risk register lists risks with their scores, owner, and decision. Each row names the threat, vulnerability, and asset (L = likelihood, I = impact, both 1–5):

ID Risk: threat → vulnerability → asset L I Score Plan
R1 Agent edits the ID in the URL → no object-level auth check → customer PII 4 5 20 Ownership check this sprint (L34)
R2 Bots exploit a known CVE → image not rebuilt in 9 months → pods and IAM role 3 5 15 Monthly rebuilds, CI scanning (L54)
R3 Insider exports a collection → one broad shared Mongo user → PII 2 5 10 Per-service DB users (L53)
R4 Scraper floods /v1/quotes → no Kong rate limit → availability 3 3 9 Kong rate-limiting plugin (L42)
R5 AWS region outage → single region → availability 1 4 4 Accept; already multi-AZ

R2 has the scariest CVSS numbers, yet R1 ranks higher: your own missing check will never get a CVE, no scanner flags it, and thousands of users can reach it today. Scores also change: if one of R2's CVEs starts being exploited in the wild, its likelihood jumps to 5.

🛠 Try it (optional, ~5 min)

  1. Open https://nvd.nist.gov/vuln/detail/CVE-2021-44228, find the CVSS 3.x section, and match each vector field to the table above. Click the vector to open NVD's calculator, change AV from Network to Local, and watch the score drop.
  2. Or use NVD's public, read-only API (needs jq):
curl -s "https://services.nvd.nist.gov/rest/json/cves/2.0?\
cveId=CVE-2021-44228" \
  | jq -r '.vulnerabilities[0].cve.metrics.cvssMetricV31[]
      | [.source, .cvssData.vectorString, .cvssData.baseScore]
      | @tsv'

You should see two lines: one from nvd@nist.gov and one from the CNA (shown as an ID). Both say 10.0 here, but for other CVEs NIST and the CNA often disagree. Since early 2024 the NVD has had a large backlog, so a recent CVE may show only the CNA's score, or "awaiting analysis".

  1. Take one CVE that Dependabot or a scanner flagged in a service you work on, and translate its vector into a single sentence like the Log4Shell one.

🧠 Key takeaways

  • Asset = what you protect; threat = what could harm it; vulnerability = the weakness; exploit = the technique that uses it. Remove asset, threat, or vulnerability and that path has no risk.
  • Risk = likelihood × impact. Controls lower one or the other; what's left is residual risk.
  • A CVE names a flaw; CVSS scores its general severity from 0.0 to 10.0.
  • A high CVSS score isn't automatically your top risk, and your worst risks may have no CVE at all.

📖 Words to know

Term Meaning
Asset Anything of value to protect
Threat / threat actor Anything that could cause harm / the person or group behind it
Vulnerability A weakness a threat could use
Exploit Code or a technique that uses a vulnerability
Zero-day A vulnerability exploited before a fix exists
Control Anything that reduces risk
Risk How likely a harmful event is, combined with how bad it would be
Residual risk Risk left after controls
CVE Public ID for a known vulnerability
CNA An organization allowed to assign CVE IDs
CVSS 0.0–10.0 severity score built from a vector string
NVD NIST's database adding scores and versions to CVEs
Risk register A list of risks with scores, owners, and decisions

⏭ Next time

L03: thinking like an attacker. The Cyber Kill Chain, what "attack surface" really means, and why a defender has to be right every time while an attacker only has to be right once.

Deep dive 1

CVSS is severity, not risk (EPSS and the CISA KEV catalog)

The trap

A common rule is "fix every Critical and High within 30 days." It sounds responsible, but it often fails in practice. Around 40,000 CVEs were published in 2024 alone, and a large share score 7.0 or higher. Yet only a small fraction of all CVEs (commonly estimated at around 5% or less) is ever seen exploited in the wild. Teams following CVSS alone drown in "Criticals" nobody attacks, while a 7.5 that criminals are actively using waits in the queue.

CVSS answers "how bad could this be?" It doesn't answer "is anyone actually doing it?" Two free, public data sources fill that gap.

EPSS: how likely is exploitation soon?

The EPSS (Exploit Prediction Scoring System), also published by FIRST, gives every CVE a probability from 0 to 1 that it will be exploited in the wild in the next 30 days. It's a data-driven model, retrained periodically and rescored daily, built from signals such as observed exploitation attempts, whether exploit code is public, and the type of flaw. Each score also has a percentile: 0.95 percentile means it's more likely to be exploited than 95% of all CVEs.

Most CVEs have EPSS scores well under 0.01. Log4Shell scores about 0.9999, in the top percentile of all CVEs. (Values change daily.)

KEV: is it being exploited right now?

The CISA KEV (Known Exploited Vulnerabilities) catalog, launched in November 2021, is a list of CVEs that the US Cybersecurity and Infrastructure Security Agency has confirmed are being exploited. To get in, a CVE needs reliable evidence of active exploitation and a clear fix or mitigation. Under Binding Operational Directive 22-01, US federal civilian agencies must fix KEV entries by a due date. Many private companies, including banks, use it as their "patch first" list.

KEV holds roughly 1,750 entries as of late 2026, out of more than a quarter of a million CVEs. It also flags entries known to be used in ransomware campaigns.

Putting the three together

                  low EPSS, not in KEV    high EPSS or in KEV
               ┌───────────────────────┬───────────────────────┐
 CVSS high     │ bad if exploited, but │ FIX NOW               │
 (7.0–10.0)    │ nobody is (yet):      │ severe AND in use     │
               │ planned patch, watch  │                       │
               ├───────────────────────┼───────────────────────┤
 CVSS low/med  │ normal patch cycle    │ don't skip it:        │
 (0.1–6.9)     │                       │ attackers chain these │
               └───────────────────────┴───────────────────────┘
    then adjust for YOUR exposure: internet-facing? what data?

The bottom-right box matters. Attackers often chain a "medium" flaw (say, an information leak) with another to get full access, so a medium in KEV beats an unexploited critical.

🧪 Worked example: triaging three findings

A scan of the example stack's EKS workloads returns three findings on the same morning (B and C are made-up but typical):

Finding CVSS EPSS KEV Exposure Decision
A: log4j-core 2.14.1 in policy-service (CVE-2021-44228) 10.0 ~1.0 Yes Internet-facing through Kong Emergency: patch today, block the attack pattern at Kong meanwhile
B: deserialization bug in a library loaded only by an offline Airflow batch job 9.8 0.002 No No network listener, internal data only Next regular patch cycle
C: path traversal in the vendor appliance at the network edge 7.5 0.6 Yes Internet-facing Patch today, ahead of B despite the lower CVSS

A pure CVSS sort would put B ahead of C. Adding exploitation data and exposure flips it. That combination, severity plus threat activity plus your own environment, is what risk means in practice. (CISA also publishes SSVC, a decision tree that formalizes this kind of triage.)

🛠 Try it (~3 min, public read-only data)

# EPSS score and percentile for Log4Shell
curl -s "https://api.first.org/data/v1/epss?cve=CVE-2021-44228" \
  | jq '.data[0]'

# Is it in KEV, since when, and is ransomware use known?
curl -s "https://www.cisa.gov/sites/default/files/feeds/\
known_exploited_vulnerabilities.json" \
  | jq '.vulnerabilities[]
        | select(.cveID=="CVE-2021-44228")
        | {cveID, dateAdded, knownRansomwareCampaignUse}'

What to look for: an epss value close to 1 and a percentile of 1.0, then a KEV entry with dateAdded 2021-12-10 and knownRansomwareCampaignUse "Known". Try the same commands on a CVE from one of your own scanner reports.

🧠 Extra takeaways

  • CVSS rates severity; EPSS estimates the chance of exploitation in the next 30 days; KEV confirms exploitation is already happening.
  • Most CVEs are never exploited, so CVSS-only patch rules waste effort and miss real threats.
  • Prioritize KEV entries and high-EPSS CVEs on exposed systems first, whatever their CVSS.
  • Exposure and data sensitivity in your own environment still adjust every decision.
Term Meaning
EPSS FIRST's daily probability (0–1) that a CVE is exploited in the wild within 30 days
EPSS percentile How a CVE's EPSS score ranks against all other CVEs
CISA KEV US government catalog of CVEs confirmed to be exploited in the wild
BOD 22-01 The 2021 directive requiring US federal agencies to fix KEV entries by a deadline
Exploit chaining Combining several lower-severity flaws into one serious attack
SSVC CISA's decision-tree method for prioritizing vulnerabilities
Deep dive 2

Risk treatment (mitigate, transfer, accept, avoid)

A score isn't a decision

The policy-api risk register says R5 (a region outage) scores 4 and R1 (reading any policy) scores 20. Fine, but what do you actually do about each? Every risk gets one of four answers, called risk treatment options. Picking one, writing it down, and naming who decided is what turns a scary spreadsheet into a managed system.

The four options

  • Mitigate (reduce): add a control that lowers likelihood or impact. Patching, an authorization check, MFA, encryption, rate limits. This is what most engineering work is.
  • Transfer (share): move the financial consequence to someone else, usually through cyber insurance or a contract. You can transfer the bill, but not the accountability: regulators and customers still hold the company responsible, and the reputational harm stays with you.
  • Accept: consciously decide to live with the risk because it's small or fixing it costs more than it saves. Acceptance must be explicit: a named owner with the authority to accept it (usually a business leader, not the developer), a written reason, and an expiry or review date.
  • Avoid: stop doing the risky thing. Retire the endpoint, don't collect the data, don't launch the feature. The risk disappears, along with whatever value the activity had.
               a risk on the register
                          │
          is the activity worth doing at all?
           │ no                            │ yes
           ▼                               ▼
         AVOID                  within the risk appetite?
     stop doing it               │ yes               │ no
                                 ▼                   ▼
                               ACCEPT        can a control cut it
                           (owner + date)      at a sensible cost?
                                              │ yes          │ no
                                              ▼              ▼
                                          MITIGATE       TRANSFER
                                                       (insurance,
                                                        contract)

Risk appetite is how much risk the organization is willing to carry, set by leadership. In real life the options combine: you mitigate most of a risk, insure part of what's left, and accept the rest. "Ignore" is not on the list. An unowned, undecided risk is the most dangerous kind.

Putting a price on it: ALE

For decisions involving money, such as whether a control or an insurance policy is worth it, teams use a classic formula:

  • SLE (single loss expectancy): the cost of one occurrence.
  • ARO (annualized rate of occurrence): how many times a year you expect it.
  • ALE (annualized loss expectancy) = SLE × ARO.
 Credential stuffing against a customer login API (made-up numbers)

 BEFORE   SLE $12,000 (fraud + investigation) × ARO 5/yr
          ALE = $60,000 a year
 CONTROL  bot detection + step-up MFA at the gateway: $20,000/yr
 AFTER    SLE $12,000 × ARO 1/yr          ALE = $12,000 a year

 saving $48,000 − cost $20,000 = $28,000/yr ahead ──▶ MITIGATE

If the control had cost $70,000 a year, it would cost more than the whole loss it prevents, and accepting or insuring the risk would make more sense. The inputs are estimates, so treat the result as a guide to a decision, not a precise forecast. FAIR (Factor Analysis of Information Risk) is a widely used method for doing this kind of estimate more rigorously, with ranges instead of single numbers.

🧪 Worked example: treating the policy-api register

ID Risk (from the main lesson) Score Treatment Why
R1 Any agent reads any policy 20 Mitigate Cheap fix, huge impact; far outside appetite
R2 Known CVEs in a stale image 15 Mitigate Automated rebuilds cost little
R3 Insider exports a collection 10 Mitigate + transfer Least-privilege DB users and audit logs; residual fraud loss covered by insurance
R4 Scraper floods /v1/quotes 9 Mitigate One Kong plugin
R5 Region outage 4 Accept Multi-region costs more than expected loss; signed by the product owner, review in 12 months
R6 Old /v0/export endpoint dumps full documents; 2 callers, both migrated 12 Avoid Delete the endpoint: removes the risk, keeps all value

R6 shows the most underrated option. Deleting unused endpoints, data, and permissions is often the cheapest security work there is.

🛠 Try it (~3 min)

Find one known risk in a service you work on that nobody has decided about: an old endpoint, a stale dependency, a shared credential. Write one line for each of the four options. Which would you choose, and who in your organization would have to sign off on accepting it?

🧠 Extra takeaways

  • Every risk gets one of four treatments: mitigate, transfer, accept, or avoid, often combined.
  • Transferring moves the cost, not the accountability or the reputational damage.
  • Acceptance needs a named owner with authority, a reason, and a review date.
  • ALE = SLE × ARO helps decide whether a control is worth its cost.
  • Avoiding (deleting unused things) is often the cheapest and most complete fix.
Term Meaning
Risk treatment The decision about what to do with a risk: mitigate, transfer, accept, or avoid
Risk appetite How much risk an organization is willing to carry, set by leadership
Risk acceptance A documented, owned decision to live with a risk for a set period
SLE Single loss expectancy: the cost of one occurrence
ARO Annualized rate of occurrence: expected occurrences per year
ALE Annualized loss expectancy: SLE × ARO
FAIR A quantitative method for estimating information risk in money terms

The quiz for this lesson and the Tests section need JavaScript.