Skip to main content

The vulnerabilities you actually encounter

Summary: application security is not an infinite field — about ten families of vulnerabilities account for the bulk of what you encounter in practice. This lesson walks through the OWASP Top 10 with clear examples, explains how to read a CVE and a CVSS score, and above all how to distinguish a theoretical vulnerability from one that is actually exploitable in your environment.


1. The OWASP Top 10 — overview

OWASP is a non-profit organization that publishes, roughly every four years, the ranking of the ten most critical risk families for web applications.

Two important observations about this ranking.

First, broken access control is in first place, and that is no accident: it is the vulnerability that is hardest to detect automatically, because no tool knows which data should be accessible to which user. It is business logic, and only a human review or dedicated tests cover it.

Second, misconfiguration (family 5) is probably the most frequent cause of real incidents, while also being the simplest to avoid. A cloud storage bucket left public, a default administrator account kept, an exposed admin interface: these are configuration errors, not code errors.


2. The three vulnerabilities to understand in detail

SQL injection

Here is the difference in code, using a deliberately simple example.

# VULNERABLE: the input is pasted into the query text
query = "SELECT * FROM products WHERE name = '" + user_input + "'"
cursor.execute(query)

# SAFE: the structure and the values travel separately
cursor.execute("SELECT * FROM products WHERE name = %s", (user_input,))

What to take away from this comparison: the protection does not consist in filtering dangerous characters — that approach is fragile and has been bypassed a thousand times. It consists in structurally separating code from data. With a parameterized query, it becomes impossible for the input to be interpreted as code, whatever its content.

Broken access control

The distinction never to forget: authentication answers "who are you?", authorization answers "do you have the right to access this?". Confusing the two is the most widespread mistake in web development.

An important point: replacing sequential identifiers with random identifiers (UUIDs) makes exploitation harder but fixes nothing. That is security through obscurity. The fix is the authorization check.

Cross-site scripting

Good news on this point: modern frameworks (React, Vue, Angular, Django, Rails) escape data by default. XSS has become far rarer than it was in 2010. It essentially reappears when this protection is deliberately disabled — for example with dangerouslySetInnerHTML in React, whose very name is an explicit warning.


3. Reading a CVE


4. Understanding the CVSS score

This is the most frequent mistake made by teams discovering security: handling vulnerabilities in descending CVSS score order. That leads to spending days on flaws that are unexploitable in your context, while leaving aside problems that are actually reachable.


5. What really matters: exploitability

The two resources to remember from this lesson:

The CISA KEV list (Known Exploited Vulnerabilities) catalogs vulnerabilities that are actively exploited in the real world. If a flaw is on it, it is a priority whatever its CVSS score — because someone is exploiting it right now.

The EPSS score (Exploit Prediction Scoring System) estimates the probability that a vulnerability will be exploited within thirty days. Combined with CVSS, it enables much fairer prioritization: a flaw rated 9.8 with an EPSS of 0.1% is less urgent than a flaw rated 7.0 with an EPSS of 40%.


6. The false positives problem

A report with 3,400 alerts is equivalent to no report — it is exactly the same mechanism as alert fatigue in observability. Twenty alerts that get handled are infinitely better than three thousand that get ignored.


Remember in 30 seconds

  • The OWASP Top 10 covers the bulk of what you encounter. Broken access control is in first place.
  • Access control is hard to detect automatically: no tool knows your business logic.
  • Misconfiguration is probably the most frequent cause of real incidents, and the simplest to avoid.
  • SQL injection: the solution is the parameterized query, which structurally separates code and data. Filtering characters is not enough.
  • Authentication ≠ authorization. Being logged in is not having the right to access this resource.
  • Replacing a sequential identifier with a UUID fixes nothing — that is security through obscurity.
  • XSS: modern frameworks escape by default. The risk comes back when the protection is disabled.
  • A CVE is a unique public identifier. CVSS measures theoretical severity, from 0 to 10.
  • Don't prioritize by descending CVSS. What matters: exposure, reachability, known exploit, data sensitivity.
  • CISA KEV = actively exploited flaws, absolute priority. EPSS = probability of exploitation within 30 days.
  • 3,400 alerts are equivalent to zero alerts. Block on critical and exploitable, track the rest.

Next: The software supply chain: dependencies and SBOM →