Oleg
Chursin
WorkNotesPhotography
What the OWASP Top 10:2025 actually measures

How the OWASP Top 10:2025 turns contributed test data, CVE scores and a survey into a ranking, and which of its numbers you can quote without misleading anyone.

Contents · 12 sections

Picture a slide in a security review: "100% of applications have broken access control", with the OWASP logo underneath. A compliance checklist has ten rows, A01 to A10, each with a tick. A backlog ranks work by Top 10 position, so Injection waits behind Cryptographic Failures because 4 comes before 5. All three treat the OWASP Top 10 as a measurement of risk in their system. None of them is what the document measures.

The Top 10:2025 is built from three different populations: applications that vendors and consultancies tested, CVE records in the National Vulnerability Database, and a few hundred people who answered a survey. Each feeds a different part of the ranking, and each number on the site has its own denominator. If you quote one as though it were another, you get the "100%" above, which the site itself prints and which is not what its own score table says.

I read the 2025 edition the way I'd read a spec: the introduction, the methodology page, all ten category pages, the "Making Of" slides Brian Glas presented at OWASP Global AppSec USA 2025, the data collection plan and the repository history. Then I re-ran the published scoring formula on the published tables. What follows is the pipeline from contributed spreadsheet row to final rank, the places where OWASP's own numbers disagree, and what I'd use the list for and what I wouldn't. It's the first part of a series on reading security standards; later parts cover ASVS, threat modeling and vulnerability scoring.

The Top 10 is an awareness document that people use as a requirements list

OWASP is clear about the genre. The Top 10:2025 home page calls it "a standard awareness document for developers and web application security" that "represents a broad consensus about the most critical security risks to web applications." The project page uses the same sentence, and it also calls the list "the reference standard for the most critical web application security risks." Those two phrases pull in different directions, and readers tend to hear the second.

The introduction calls this the 8th installment and says it has "two new categories and one consolidation." The list, as of October 2026:

  1. A01:2025 Broken Access Control
  2. A02:2025 Security Misconfiguration
  3. A03:2025 Software Supply Chain Failures
  4. A04:2025 Cryptographic Failures
  5. A05:2025 Injection
  6. A06:2025 Insecure Design
  7. A07:2025 Authentication Failures
  8. A08:2025 Software or Data Integrity Failures
  9. A09:2025 Security Logging and Alerting Failures
  10. A10:2025 Mishandling of Exceptional Conditions

OWASP also has data on how people use it. The project's community survey asked respondents what the Top 10 does for them, and the answers are on a slide in the Making Of deck. The largest group, 145 responses, said it "helps provides structure for standards, requirements, security tests, test results". 129 said it's mostly for developer education, 85 said they must follow compliance rules that reference it, 79 build processes around it and 46 build tools to test for it.

That is the gap this piece is about. An awareness ranking of categories, built from industry-wide averages, is being used as a source of requirements and test structure. The ranking can do some of that job. To know which part, you need to know what went into it.

The data counts applications, not findings

The contributed data has an unusually simple shape. The 2025 Data Analysis Plan marks two fields as required for each dataset: the number of applications tested, and the CWEs found with the number of applications each was found in. Everything else is context: contributor, type of testing, primary language, region, industry, and whether the data contains retests. The time period (one of 2021 to 2024) isn't starred in the plan, but every example record carries it. The Making Of deck shows the minimum record as four values, with the example 2021, CWE-89, 1000, 200: year, CWE, population tested, applications with at least one instance.

The introduction explains why frequency is thrown away: "Whether an application has four instances of a CWE or 4,000 instances is not part of the calculation." Manual testers tend to report a weakness once per application, while automated tools report every instance. Counting applications instead of findings puts both on the same footing. The deck describes this as borrowing from epidemiology: incidence in a population, not a count of cases.

So the core unit is the incidence rate, which the methodology page defines as "the percentage of applications vulnerable to that CWE from the population tested by that org for that year." It's per contributor, per CWE, per year. Here is the arithmetic on the CWE-20 rows of OWASP's own sample submission file. The rows are OWASP's example data, not real findings, but the shape is the real one:

incidence.mjs
// The CWE-20 rows from OWASP's 2025 sample-data-submission.csv.
const rows = [
  { year: 2021, cwe: 20, tested: 100, found: 53 },
  { year: 2022, cwe: 20, tested: 100, found: 10 },
  { year: 2023, cwe: 20, tested: 100, found: 30 },
];

// Incidence: share of this contributor's tested apps, that year,
// with at least one instance. 1 finding or 4,000 count the same.
const incidence = rows.map((r) => r.found / r.tested);

const max = Math.max(...incidence);
const avg = incidence.reduce((a, b) => a + b, 0) / incidence.length;

console.log({ max, avg: Number(avg.toFixed(4)) });
// { max: 0.53, avg: 0.31 }

I ran this in Node 24.18. Keep the two outputs in mind, because the ranking formula uses the maximum and the prose quotes the average. If the category maximum is taken across contributor-years, which the definition suggests but no page confirms, one high cell sets it.

The second measure is coverage: "the percentage of applications tested by all organizations for a given CWE," per the same methodology page. The page adds that "the higher the calculated coverage, the stronger the assurance that the incidence rate is accurate." Coverage tells you how many applications were checked for something. It says nothing about how many had it. Mixing the two produces the edition's most slide-ready wrong number, which gets its own section below.

A few more facts about the population:

  • Size. The introduction credits 12 named organizations "along with several anonymous donors" with data "for over 2.8 millions applications." The deck says "2.8 million applications (conservatively)."
  • Window. The plan set a deadline: "We plan to accept contributions to the Top 10 2025 until July 31, 2025, for data dating from 2021 to 2024." It doesn't say whether late data was taken. The deck's process slide says of the data request: "It takes 14-16 months."
  • Trust levels. The plan accepts known and anonymous contributors. Anonymous data is classed as "unverified", and the plan promises a "careful distinction when the unverified data is part of the dataset that was analyzed." The published pages don't say how large the unverified share was.
  • Testing type. The plan asks contributors to label each dataset as Tool-assisted Human (TaH), Human-assisted Tools (HaT) or Tools, and recommends submitting HaT and TaH data as separate datasets. The goal is data "normalized to allow for level comparison" between them. The normalization itself isn't published.

Exploit and impact come from CVEs, not from the contributed apps

The incidence and coverage numbers say how common a weakness is in tested applications. They say nothing about how bad it is. For that, the Top 10 goes to a completely different dataset.

The introduction says the team downloaded OWASP Dependency Check and extracted CVSS exploit and impact sub-scores from the NVD data it carries, grouped by the CWEs listed on each CVE. That gave about 175,000 CVE-to-CWE records (up from 125,000 in 2021) and 643 unique CWEs mapped to CVEs (up from 241). "Within the nearly 220k CVEs that were extracted, 160k had CVSS v2 scores, 156k had CVSS v3 scores, and 6k had CVSS v4 scores." The deck gives the exact counts: 219,291 CVEs, of which 159,544 had v2, 156,407 had v3 and 6,299 had v4.

Combining v2 and v3 needs a correction, because the two versions scale their sub-scores differently. The methodology page explains that in v2 both exploit and impact could reach 10.0 but were knocked down to 60% and 40% in the base score, while v3 caps them at 6.0 and 4.0. For 2025, the team "grouped all the CVEs with CVSS scores by CWE and weighted both exploit and impact scores by the percentage of the population that had CVSSv3, as well as the remaining population with CVSSv2 scores." The result is placed on a 10-point scale and mapped back onto each CWE.

CVSS v4.0 isn't used at all. The introduction says why: the v4 "scoring algorithm was fundamentally changed, and it no longer easily provides the Exploit or Impact scores as CVSS v2 and CVSSv3 do." The team says it will try to use v4 next time. For this edition, that means the severity half of the ranking rests on CVSS versions 2 and 3, not 4.0, and on CVEs from whatever period the Dependency Check feed covered. The site doesn't state that period.

Two consequences follow, and both are easy to miss.

First, the halves of the formula describe different worlds. Incidence comes from private test results on 2.8 million applications. Exploit and impact come from public CVE records, which describe vulnerabilities in software someone ships or publishes: libraries, frameworks, appliances, CMS plugins. An IDOR bug in your internal line-of-business app is unlikely ever to get one. The severity score its category carries is inherited from other people's published vulnerabilities in the same CWEs.

Second, CVE volume shapes the averages. The deck lists the CWEs with the most CVE mappings. CWE-79 (cross-site scripting) leads with 30,431. The next two are not weaknesses at all: NVD-CWE-Other with 24,309 and NVD-CWE-noinfo with 21,869. Then CWE-89 (SQL injection) with 14,145. The A05 Injection page says the "massive number of reported CVEs for CWE-79" brings down the category's average weighted impact. A category average is only as meaningful as the mix of CWEs under it.

Fig. 1 traces the pipeline end to end. The Making Of deck gives the same sequence as a list: ask for data, normalize it, pull NVD for CVE-to-CWE mappings, normalize exploit and impact, group CWEs into categories, set the formula weights, build a data Top Ten, run the survey, weigh the survey with the data, and write.

Hundreds of CWEs go into ten buckets of very different sizes

The 2021 edition stopped asking contributors for a fixed set of about 30 CWEs, and 2025 kept that open format. The introduction says the analysis went "from approximately 30 CWEs in 2017, to almost 400 CWEs in 2021, to 589 CWEs in this edition." The Making Of deck gives different numbers for the same series: 30, 390 and 686. Both are OWASP's own sources. I can't tell which is right from what's published, and I come back to it at the end.

Those hundreds of CWEs were then grouped by hand. "We spent several months grouping and categorizing CWEs and could have continued for additional months. We had to stop at some point," the introduction says. The team grouped by root cause rather than symptom where it could: "Cryptographic Failure" rather than "Sensitive Data Exposure". The final ten hold 248 CWEs, an average of about 25 per category. The cap is 40, reached by A01. The floor is 5, for A03 and A09, according to the introduction. For context, it notes MITRE's downloadable dictionary held 968 CWEs at release.

The buckets are very different sizes, and that matters for the formula in the next section. Counting each category page's "List of Mapped CWEs" on 18 October 2026, I got 40, 16, 6, 32, 37, 39, 36, 14, 5 and 24 for A01 to A10. That sums to 249, not 248. The one-CWE difference is A03, which I'll explain below.

Why not rank individual CWEs, like MITRE does? The introduction gives two reasons. Not every CWE exists in every language or framework, so a list of single CWEs would leave some of it irrelevant to each reader. And common vulnerabilities often have several CWEs, so different testers file the same bug under different numbers. A category gathers them.

The contrast with the 2025 CWE Top 25 is useful, because it shows a different answer to the same question. Per MITRE's 2025 methodology, the Top 25 uses no private test data at all. It analyzed 39,080 CVE records published between June 1, 2024 and June 1, 2025, sent 9,468 records with doubtful CWE mappings back to the CVE Numbering Authorities for review, and scored each CWE by multiplying normalized frequency (how often it is the root cause of a CVE) by normalized average CVSS v3.x severity. CWE-79 is first, with a score of 60.38, and CWE-89 second at 28.72.

So the two lists measure different things:

OWASP Top 10:2025 CWE Top 25 (2025)
Unit ranked Category of 5 to 40 CWEs Single CWE
Prevalence from Private test results, applications with at least one instance Public CVE records
Severity from CVSS v2 and v3 exploit and impact sub-scores, by CWE CVSS v3.x base score
Time window Contributed data for 2021 to 2024 CVEs published June 2024 to June 2025
Human judgement CWE grouping, weights, survey CVE remapping with CNAs

Neither one is "right". If someone tells you XSS isn't a big deal because Injection fell to fifth, point them at the Top 25, which ranks CWE-79 first on a year of CVEs. Both lists can be right about what they measure.

The risk score rewards the biggest buckets

Each category gets one number. The methodology page gives the formula:

(Max Incidence Rate % * 1000) + (Max Coverage % * 100) + (Avg Exploit * 10) + (Avg Impact * 20) + (Sum Occurrences / 10000) = Risk Score

The percentages enter as fractions. If you plug in 20.15 for A01's maximum incidence rate, that term alone is 20,150, and the page says scores "ranged from 621.60 for the category of Broken Access Control to 271.08 for Memory Management Errors." The scores only fit that range if 20.15% enters as 0.2015.

Here is the worked example for A01, using its score table: max incidence 20.15%, max coverage 100.00%, average weighted exploit 7.04, average weighted impact 3.84, total occurrences 1,839,701.

Term Value Weight Points
Max incidence 0.2015 × 1000 201.50
Max coverage 1.0000 × 100 100.00
Avg exploit 7.04 × 10 70.40
Avg impact 3.84 × 20 76.80
Occurrences 1,839,701 ÷ 10,000 183.97
Total 632.67

That doesn't match the 621.60 on the methodology page. It does match the Making Of deck, whose "Data Factors" slide shows Broken Access Control at 632.68, with the same per-term points to rounding. So the deck and the category table agree with each other, and the methodology page's headline number is the odd one out. The low end of the range, Memory Management Errors at 271.08, matches the deck exactly. I don't know where 621.60 came from.

Incidence and occurrences do the separating

Look at the five terms as a budget. Coverage is worth at most 100 points, and six of the ten categories score the full 100 because at least one of their CWEs was tested in every application. Average exploit ranges from 6.96 to 8.17 across the ten, worth about 12 points after weighting; impact ranges from 2.65 to 5.23, worth about 52. Incidence and occurrences do most of the separating.

Occurrences is the term to watch. It's "the total number of applications found to have the CWEs mapped to a category." It's a sum across CWEs, so it grows with the number of CWEs you put in a bucket. A01, with 40 CWEs, gets 184 points from it. A03, with 6, gets 22. The deck's "Contribution" slide shows the share: occurrences make up 29% of Broken Access Control's score and 6% of Software Supply Chain Failures'. Grouping decisions made by hand, with the team saying they "had to stop at some point," feed straight into the ranking through this term.

The maximum incidence term has a similar sensitivity. It takes the single highest rate among a category's CWEs, so a category with one high-incidence CWE scores the same here as one where every CWE is that common.

Halving one weight reorders the middle of the list

I wrote the formula as code and ran it on the ten published category tables. The rows are copied from the pages as they stood on 18 October 2026:

risk-score.mjs
// Score tables from the A01-A10 pages at top10.owasp.org/2025,
// read 2026-10-18. Rates are fractions: 20.15% is 0.2015.
// [id, maxIncidence, maxCoverage, exploit, impact, occurrences]
const rows = [
  ['A01', 0.2015, 1.0, 7.04, 3.84, 1839701],
  ['A02', 0.2770, 1.0, 7.96, 3.97, 719084],
  ['A03', 0.0956, 0.6542, 8.17, 5.23, 215248],
  ['A04', 0.1377, 1.0, 7.23, 3.90, 1665348],
  ['A05', 0.1377, 1.0, 7.15, 4.32, 1404249],
  ['A06', 0.2218, 0.8876, 6.96, 4.05, 729882],
  ['A07', 0.1580, 1.0, 7.69, 4.44, 1120673],
  ['A08', 0.0898, 0.7852, 7.11, 4.79, 501327],
  ['A09', 0.1133, 0.8596, 7.19, 2.65, 260288],
  ['A10', 0.2067, 1.0, 7.11, 3.81, 769581],
];

// The published weights: incidence x1000, coverage x100,
// exploit x10, impact x20, occurrences / 10,000.
const published = [1000, 100, 10, 20, 1 / 10_000];

function ranking(weights) {
  return rows
    .map(([id, ...values]) => ({
      id,
      score: values.reduce((sum, v, i) => sum + v * weights[i], 0),
    }))
    .sort((a, b) => b.score - a.score);
}

const fmt = (list) => list.map((r) => r.id).join(' ');

console.log(fmt(ranking(published)));
// A01 A02 A04 A05 A07 A06 A10 A08 A03 A09
console.log(fmt(ranking([1000, 100, 10, 20, 1 / 20_000])));
// A02 A01 A06 A10 A07 A04 A05 A08 A03 A09

With the published weights, this reproduces the data order the deck reports for these ten: Broken Access Control, then Misconfiguration, Cryptographic Failures, Injection, Authentication, Insecure Design and Exceptional Conditions. Then halve one weight, so occurrences count per 20,000 instead of per 10,000. Misconfiguration overtakes Broken Access Control, and Injection drops from fourth to seventh among these ten.

That's not an argument that the published weights are wrong. Every ranking needs weights, and OWASP's team chose these "with some weighting changes" from 2021, per the methodology page. It's an argument about precision. The deck's data scores for ranks 4 to 7 are 535.96, 535.74, 534.19 and 531.00, a spread of under 5 points on scores above 500. At that margin, "Injection is fifth" means "Injection is in a cluster of four categories that scored about the same."

One caveat about my run: it only has the ten published categories, and only their aggregates. The real computation ran on CWE-level data across twelve candidate categories, which hasn't been published. A reweighting could move the two unpublished categories too.

"100%" is a coverage number, and the site prints it as incidence

Here is the sentence that ends up on slides. The A01 page begins: "Maintaining its position at #1 in the Top Ten, 100% of the applications tested were found to have some form of broken access control."

The same page's score table says otherwise. Average incidence rate is 3.74%. Maximum incidence rate is 20.15%. Maximum coverage is 100.00%. The introduction agrees with the table: "on average, 3.73% of applications tested had one or more of the 40" CWEs in the category. (The 3.73% versus 3.74% is a separate rounding difference I can't explain.)

So 100% is the coverage figure. Every application was tested for some form of broken access control. On average, a few percent of them were found to have it, and in the worst contributor-year, about a fifth. The 2021 A01 page used the right construction for the same idea: "94% of applications were tested for some form of broken access control with the average incidence rate of 3.81%." And the 2025 A05 page gets it right too: "100% of applications tested for some form of injection."

This was reported, by one of the project's own lead authors. Issue #841, opened by Brian Glas on 16 November 2025, proposed "100% of the applications were tested for some form of broken access control" and was closed as fixed on 5 December 2025. Then, on 24 December 2025, commit 2616377, a rebase of an older pull request, changed the sentence back to "tested were found to have", listing it as a clarity fix. That's the wording live today. In July 2026, a comment on the still-open issue #898 raised the A01 mismatch again, saying it mixes coverage with incidence.

The A02 page has the same construction: "100% of the applications tested were found to have some form of misconfiguration, with an average incidence rate of 3.00%." Its table again shows 100.00% maximum coverage. I haven't found an issue that raises A02. My reading is that it's the same coverage-as-incidence slip, because the sentence itself states a 3.00% average incidence.

Fig. 2 puts the three numbers side by side for A01, A03 and A05. When you quote the Top 10, name the metric. Something like: "In the OWASP Top 10:2025 data, every application was tested for broken access control, and on average 3.74% of tested applications had at least one of its 40 CWEs (A01 score table)." It's longer. It's also true.

Five more places where prose and table disagree

A01 isn't the only page where prose and table disagree. Here's what I found on 18 October 2026:

Where Prose says Table or list says
A01 "100% of the applications tested were found to have" Avg incidence 3.74%, max coverage 100%
A02 "100% ... found to have some form of misconfiguration" Avg incidence 3.00%, max coverage 100%
A03, CWE count Introduction: 5 CWEs; background names 4 Table: 6 CWEs mapped; list has 6
A03, incidence "highest average incidence rate at 5.19%" Avg incidence 5.72%
A05, CWE count Introduction: 38 CWEs Page and list: 37
Score range Methodology page: A01 scored 621.60 Deck and table arithmetic: 632.67 to 632.68

The A03 rows have a traceable cause. On 24 December 2025, commit d705984 added CWE-1357 (Reliance on Insufficiently Trustworthy Component) to A03 and updated the table: 5 CWEs became 6, max incidence 8.81% became 9.56%, average incidence 5.19% became 5.72%. The prose and the introduction weren't updated. The deck's data score for supply chain uses 88.14 incidence points, which matches the old 8.81%. So the ranking was computed before the CWE was added. With the new table, my code gives A03 368.84 instead of the deck's 361.42. It's still tenth in the data either way. A comment on issue #898 flagged the 5.19% versus 5.72% mismatch in January 2026, and a maintainer said in April that it still needed checking.1

None of this changes the order of the list. But a reader who quotes "5 CWEs" or "5.19%" and a reader who quotes "6" and "5.72%" are both quoting OWASP, and they'll disagree.

The survey decides the bottom of the list

The data ranking only gets you most of the way. The introduction's methodology section says: "We ranked 12 categories based on the data contributed, and allowed two to be promoted or highlighted by responses from the community survey." The reason is that data "is essentially looking into the past": it takes years for a new class of weakness to get tooling that tests for it at scale. A few paragraphs later the same page says "we only pick eight of the ten categories from the data."

The deck has both halves. Here is the data ranking from its "Data Factors" slide:

Data rank Category Data score Final 2025
1 Broken Access Control 632.68 A01
2 Security Misconfiguration 607.89 A02
3 Cryptographic Failures 554.56 A04
4 Injection 535.96 A05
5 Authentication Failures 535.74 A07
6 Insecure Design 534.19 A06
7 Mishandling of Exceptional Conditions 531.00 A10
8 Lack of Application Resilience 521.95 not listed
9 Software or Data Integrity Failures 385.22 A08
10 Software Supply Chain Failures 361.42 A03
11 Logging & Alerting Failures 350.20 A09
12 Memory Management Errors 271.08 not listed

And here's the survey, from the "Survey Results" slide. It had 225 submissions, and the slide counts first, second and third-place votes for six categories. Those six are exactly data ranks 7 to 12:

Survey rank Category #1 votes #2 #3 Score
1 Software Supply Chain Failures 106 37 24 522
2 Software or Data Integrity Failures 32 50 45 273
3 Logging & Alerting Failures 18 43 42 200
4 Lack of Application Resilience 19 38 41 193
5 Mishandling of Exceptional Conditions 22 25 40 178
6 Memory Management Errors 15 13 12 98

The deck doesn't state the scoring rule, but every row matches 4 points for a first-place vote, 2 for second and 1 for third. For supply chain, 106 × 4 + 37 × 2 + 24 = 522.

The A03 page says the category was "top-ranked in the Top 10 community survey with exactly 50% respondents ranking it #1." That checks out against the 212 people who cast a first-place vote: 106 of 212. Against all 225 submissions it's 47%. Denominators again.

Now put the tables together, as Fig. 3 does. The six categories at data ranks 1 to 6 all made the list. From the six that went to the survey, four made it: survey ranks 1, 2, 3 and 5. Lack of Application Resilience was eighth in the data and fourth in the survey, and it isn't on the list. Mishandling of Exceptional Conditions was seventh in the data and fifth in the survey, and it is.

Final positions 8, 9 and 10 follow the survey order of the three categories in them (2, 3, 5), not their data order (9, 11, 7). Supply chain jumps from tenth in the data to third overall, which the introduction explains as "overwhelmingly voted a top concern in the community survey". And within the top six there's one more swap the deck notes without explaining: "Authentication stays at 7th (data was 5th)", while Insecure Design, data sixth, sits at sixth. Their data scores differ by 1.55 points.

I can't reconcile the published rule ("eight of the ten categories from the data", "two to be promoted") with the published ranks. Either some categories count as both, or the rule was applied with judgement the pages don't describe. That's not a scandal. The introduction is explicit that the list is "data-informed, but not blindly data-driven." It does mean the bottom half of the 2025 list reflects practitioner opinion as much as test data, and you should know that before you treat A08 to A10 as measured.

A03's thin data points at a testing blind spot

Supply chain is the clearest case for the survey. Its score table has the fewest CVEs of any category, 11, and the fewest total occurrences, 215,248. It also has the highest average weighted exploit (8.17) and impact (5.23) scores, and the highest average incidence among applications that were tested for it. The introduction reads this as a testing gap: "we believe this is due to challenges in testing and hope that testing catches up in this area."

The A09 page makes the same argument for logging, which "will always be underrepresented in the data" and has "only 723 CVEs." For the third time, it was voted onto the list by the survey. If no tool or tester in the contributing population looks for a weakness, it can't show up in this kind of data. Ask whether anyone's tooling can detect a weakness before you read its rank as rarity.

A rank change is not a trend line

The introduction lists what changed since 2021. Server-Side Request Forgery, A10:2021, was rolled into Broken Access Control. A03 Software Supply Chain Failures expands A06:2021 Vulnerable and Outdated Components to "compromises occurring within or across the entire ecosystem of software dependencies, build systems, and distribution infrastructure." A10 Mishandling of Exceptional Conditions is new, with 24 CWEs, some of them previously filed under poor code quality, per the A10 page. Authentication and logging got small renames.

It's tempting to read the moves as news. Injection "fell" from third to fifth. Cryptographic Failures fell from second to fourth. The A06 page attributes Insecure Design's drop from fourth to sixth to "noticeable improvements in the industry related to threat modeling and a greater emphasis on secure design."

Maybe. But a rank can move for at least four reasons that have nothing to do with the industry getting better or worse:

  • Re-bucketing. A01 had 34 CWEs in 2021, per the 2021 introduction, and 40 in 2025, including SSRF. Because occurrences are summed across CWEs, adding CWEs adds points. A category that gains CWEs can rise without any change in the applications.
  • Different contributors. The 2021 introduction thanks 12 named organizations for data on "over 500,000 applications". The 2025 list also names 12, for over 2.8 million, and only Contrast Security, Probely and Veracode appear on both. The data plan asks for testing type, language, region and industry, but no breakdown by those fields has been published. A new large contributor with a different tool can move incidence on its own.
  • Different weights. The methodology page says the formula is "similar to 2021, with some weighting changes." The 2021 and 2025 scores aren't on the same scale.
  • The survey. The introduction says Insecure Design fell because Misconfiguration and Supply Chain "leapfrog it". Misconfiguration's rise came from the data. Supply chain's came from the survey: it was tenth in the data.

To be clear, the maintainers treat the order as the result of a fixed process. When issue #849 argued that Cryptographic Failures should be ranked first because of post-quantum migration, they declined. Neil Smithline wrote that "the ordering was based on data, not our opinions," in the same comment that says the team "had to do some massaging" to align CWEs with categories. Brian Glas said he wasn't willing to "subvert the process." Tanya Janca's reply named both inputs: "the data we received, and the feedback from the community." Refusing a lobbying request is the right call for a published standard. It also means the ranks are what the process produced, and the process includes the hand grouping, the weights and the survey.

A ranking of categories can't see your system

Even with every number quoted correctly, the Top 10 answers a different question from the one your team has.

It sees what tools can test. The introduction says plainly: "The results in the data are largely limited to what the industry can test for in an automated fashion." All three testing types the data plan lists (TaH, HaT and Tools) have a tool in the loop. I'd expect business logic flaws, and authorization bugs that only show up with two user accounts, to be undercounted in data built that way, though no published breakdown lets anyone check. The survey exists to correct for this. It's 225 people, though, not a measurement.

It averages across everyone. Category averages hide CWE-level variance, as the XSS effect on A05's impact shows. They also hide your stack: the introduction notes that "not all CWEs exist in all programming languages or frameworks." A Go service with no templates and a PHP CMS have different risk profiles, and the ranking blends them.

Its unit is wobbling. The methodology page warns that "the definition of an 'application'" is getting harder as the industry moves to microservices: "if an organization is testing code repositories, what does it consider an application?" Incidence is "applications with at least one instance". If one contributor counts a monorepo as one application and another counts each service, their rates aren't comparable.

It knows nothing about your exposure. OWASP's own methodology page says this best. Its risk table has columns for threat agents and business impacts, and it fills them in only as "By environment, dynamic by situation picture" and "By Business", because "each organization is unique, and so are the threat actors for that organization." The page's example is a content management system used for public information versus the same system holding health records: same software, different risk.

None of this is hidden. It's on OWASP's own pages. The trouble starts when a checklist, a vendor dashboard or a slide keeps the ten names and drops the caveats.

Use the Top 10 as a shared vocabulary, not a backlog

Here's my position after reading all of it. The Top 10:2025 is a good shared vocabulary and a reasonable map of where industry-wide testing finds problems. It isn't a requirements document, a prioritization for your system, or a trend report. Use it for what it is.

Use it for awareness and taxonomy. It works well as the first page of developer training and as a common language between security and engineering. The category pages each list their mapped CWEs, and that list is the most reusable part of the edition. When your scanner reports CWE-639, you can say it's A01 and everyone knows the neighborhood. The Making Of deck closes with advice to contributors that's equally good for consumers: map findings to CWEs, prefer root-cause CWEs, and stop using prohibited ones.

Use ASVS for requirements. If you need testable statements of what "secure" means, that's what the Application Security Verification Standard is for. Its current stable release is 5.0.0, published 30 May 2025. The next part of this series turns ASVS requirements into tests.

Use threat modeling to prioritize your system. The Top 10 can't tell you whether broken access control or supply chain is your bigger problem this quarter. A data flow diagram of your system and the question "what can go wrong here?" can. That's part 3 of this series.

Use vulnerability-specific signals for triage. For deciding which finding to fix first, exploit evidence beats a category's rank: CVSS for severity, EPSS for the estimated probability that a CVE is exploited in the next 30 days, and CISA's Known Exploited Vulnerabilities catalog for what has been exploited in the wild. Part 4 covers how those three fit together.

When you quote a number, name the metric and the edition. "OWASP Top 10:2025, A01 score table: average incidence 3.74%, maximum coverage 100%." Not "100% of apps have broken access control." If you can't tell which column a number came from, don't put it on a slide.

Don't rank work by Top 10 position. A05 and A07 differ by 0.22 data points, and the survey reordered the bottom of the list. Positions 4 to 7 are a tie for engineering purposes, and positions 8 to 10 are partly a poll.

What we don't know

Whether the 2025 dataset will be published. The data plan promises to "keep a version of the raw data contributed for future analysis." As of 18 October 2026, the repository's 2025/Data folder holds only the README and two sample files. The 2021/Data folder does include a few contributor submissions. The introduction still says "we plan to do additional data analysis as a supplement in the future," which is word for word what the 2021 introduction said. I didn't find a published supplement for either edition. Without CWE-level data, nobody outside the team can re-run the ranking.

Which "CWEs analyzed" count is right. The introduction says 589 for 2025 and "almost 400" for 2021. The deck says 686 and 390. They might count different things, such as CWEs present in contributed data versus all CWEs considered, but neither source says.

Where 621.60 came from. The methodology page gives A01's score as 621.60. The deck and the published table both give about 632.7. The sentence arrived on 5 November 2025 in commit 1d71853, in the same change that added the formula, and it hasn't been edited since. The deck PDF's metadata dates it to 17 November 2025. That ordering fits a figure from an earlier run of the numbers, but no OWASP source says so.

How "max incidence" is taken. The definition makes incidence per contributor, per CWE, per year. The pages don't say whether the category's "max" is the highest rate across all of those cells, or across CWEs after averaging over contributors. If it's the former, one small contributor-year can set a category's largest term. The same question applies to how "average incidence" is weighted.

How the survey and data were combined. The stated rule is eight from data and two from the survey. The published ranks show six from the top of the data and four from the survey pool, with Lack of Application Resilience dropped despite a higher data rank and survey rank than Mishandling of Exceptional Conditions. Its CWEs may have been folded into A10, whose page mentions "a lack of application resilience", but no OWASP source says so. The Authentication and Insecure Design swap is also unexplained.

Whether the A01 and A02 sentences will be corrected. Issue #841 was closed as fixed, then the wording was reverted. Issue #898 is open. I'd treat the score tables as authoritative until a maintainer says otherwise.

How the unverified and anonymous data was weighted. The plan promises a "careful distinction" for unverified data. The published pages don't say how much of the 2.8 million applications came from anonymous contributors, or whether they were weighted differently.

Notes

  1. Two smaller oddities on the A03 page. Its mapped list starts with "CWE-447 Use of Obsolete Function", but CWE-447 is "Unimplemented or Unsupported Feature in UI"; the background paragraph names CWE-477, which is Use of Obsolete Function. And CWE-1035 in the same list isn't a weakness: it's MITRE's category for the 2017 Top 10's A9. ↩︎

References

  1. OWASP Top 10:2025. OWASP. Accessed .
  2. Introduction - OWASP Top 10:2025. OWASP. Accessed .
  3. What are Application Security Risks? - OWASP Top 10:2025. OWASP. Accessed .
  4. A01:2025 Broken Access Control. OWASP. Accessed .
  5. A02:2025 Security Misconfiguration. OWASP. Accessed .
  6. A03:2025 Software Supply Chain Failures. OWASP. Accessed .
  7. A04:2025 Cryptographic Failures. OWASP. Accessed .
  8. A05:2025 Injection. OWASP. Accessed .
  9. A06:2025 Insecure Design. OWASP. Accessed .
  10. A07:2025 Authentication Failures. OWASP. Accessed .
  11. A09:2025 Security Logging and Alerting Failures. OWASP. Accessed .
  12. A10:2025 Mishandling of Exceptional Conditions. OWASP. Accessed .
  13. The Making Of the OWASP Top Ten 2025 (slides, Brian Glas). OWASP Top 10 project. Accessed .
  14. OWASP Top 10 2025 Data Analysis Plan. OWASP Top 10 project. Accessed .
  15. OWASP Top 10 2025 sample data submission (CSV). OWASP Top 10 project. Accessed .
  16. OWASP Top 10 repository, 2025/Data folder. OWASP Top 10 project. Accessed .
  17. OWASP Top 10 repository, 2021/Data folder. OWASP Top 10 project. Accessed .
  18. OWASP Top 10 project page. OWASP. Accessed .
  19. Introduction - OWASP Top 10:2021. OWASP. Accessed .
  20. A01:2021 Broken Access Control. OWASP. Accessed .
  21. Issue #841: Description in A01:2025 Broken Access Control is incorrect. GitHub (OWASP/Top10). Accessed .
  22. Commit 2616377: A01 - Improve clarity and streamline content. GitHub (OWASP/Top10). Accessed .
  23. Issue #898: Typos in the 2025 version. GitHub (OWASP/Top10). Accessed .
  24. Commit d705984: Update CVE statistics and add CWE-1357 reference. GitHub (OWASP/Top10). Accessed .
  25. Issue #849: A04:2025 Cryptographic Failures - reconsider placement. GitHub (OWASP/Top10). Accessed .
  26. 2025 CWE Top 25 Most Dangerous Software Weaknesses. MITRE. Accessed .
  27. 2025 CWE Top 25 Methodology. MITRE. Accessed .
  28. CWE-447: Unimplemented or Unsupported Feature in UI. MITRE. Accessed .
  29. CWE-1035: OWASP Top Ten 2017 Category A9. MITRE. Accessed .
  30. Commit 1d71853: methodology page adds the formula and score range. GitHub (OWASP/Top10). Accessed .
  31. Exploit Prediction Scoring System (EPSS). FIRST. Accessed .
  32. Known Exploited Vulnerabilities Catalog. CISA. Accessed .
  33. OWASP ASVS releases (5.0.0). OWASP. Accessed .

Found this useful? Pass it on.

Set in Archivo on a twelve-column grid. Built with Lit web components and rendered to static HTML.

© 2026 Oleg Chursin
Brooklyn, New York