Dev Study
← OWASP Top 10 の群 — 何のリストで、どう作られ、どう読むか
レッスン 2 / 12·約 8 分·第27期 OWASP Top 10 の群

数えたのは「見つかった数」ではなく「持っていたアプリの割合」 — Web 2025

リクエストがアプリケーションに届くまで
  1. ブラウザURL入力
  2. DNS名前→IP
  3. ルータ経路選択
  4. ロードバランサ振り分け
  5. Nginx受け口
  6. アプリ処理今ここ
  7. DB保存

Top 10 の番号を読む前に、その一覧が何をどう数えたかを読みます。今回は Web 2025 の数える単位を、提出形式の列と表の値まで降りて確かめます。

まず結論

Web Top 10 2025 が提供者に求めたのは、検査したアプリの数と、CWE ごとにそれを1つ以上持っていたアプリの数です。1つのアプリに同じ弱点が4件あっても4,000件あっても、計算上は同じ1つです。

順位の式は公開されていますが、表の値を入れても公表の値と順位は再現しません。文書自身も「完全な仕組みではない」と書いています。順位は表から機械的に出るものではない、と読みます。

? 読む前に予測

Web Top 10 2025 がデータ提供者に必須として求めた数は、次のどれでしょうか。

当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。

抽象原理

数える単位は、所見ではなくアプリ

この一覧が何を数えたか。 Web Top 10 2025 は、提供者から「検査したアプリの数」と「CWE ごとに、それを1つ以上持っていたアプリの数」を集め、割合(発生率)を出しました。募集したのは2021〜2024年のデータで、導入文は data for over 2.8 millions applications、分析した CWE は 589 と書きます(MITRE の辞書全体は 968)。これに、NVD で CWE に対応づけられた CVE の CVSS から取った Exploit と Impact、コミュニティ調査を組み合わせています。

We asked for the number of applications tested for a given year (starting in 2021), and the number of applications with at least one instance of a CWE found in testing.

件数を捨てる理由も同じ段落にあります。

Whether an application has four instances of a CWE or 4,000 instances is not part of the calculation for the Top Ten. Especially as manual testers tend to only list a vulnerability once no matter how many times it is repeated in an application, while automated testing frameworks list every instance of a vulnerability as unique.

手動検査は同じ弱点をアプリにつき1回だけ書く傾向があり、自動ツールは全箇所を書きます。件数を足すと、弱点の多さではなく検査の方法の違いを足すことになります。

Web 2025 で、所見がどこでアプリの数に畳まれるか
自動ツールの所見同じ弱点を全箇所書く
手動検査の所見同じ弱点はアプリにつき1回の傾向
提出形式でアプリ単位に畳む
NumberofAppsTested検査したアプリの数
NumberofAppsPerその CWE を持っていたアプリの数
提供者ごとに割る
発生率表の Max / Avg
ほかの入力と組み合わせる
CVE の Exploit / ImpactNVD の CVSS v2・v3 から
Risk Score の式0x02 に公開
コミュニティ調査データに写りにくい項目
  • ・件数(frequency)はどの段にも入らない
  • ・最後の段の組み合わせは、表の値だけからは再現できない(後半で確かめる)
具体実物

公式の列名で模擬データを作り、並べ替える

提出サンプル CSV の1行目は次のとおりで、件数の列がありません。

NumberofAppsTested,CWE,NumberofAppsPer,TimePeriod,ContributorName,ContributorContactEmail,TypeofTesting,PrimaryLanguage,Region,Industry,Retest

この列で模型のデータを作りました。架空の提供者は2つ。ツール提供者(100アプリ)は CWE-79 を4アプリに1,000件ずつ、CWE-862 を60アプリに1件ずつ書きます。手動の提供者(50アプリ)は各アプリ1回だけ書きます。件数は形式に載らないので、比較用に別に持ちました。乱数は使っていません。環境は macOS 26.5.2(arm64)、Python 3.14.6 です。

$ python3 a_mock_submission.py(生出力。2回実行し、日時の行を除いて同一)コマンド出力
# run 1 2026-09-28 19:23:58 JST macOS 26.5.2 arm64 Python 3.14.6
=== mock submission (official columns) ===
NumberofAppsTested,CWE,NumberofAppsPer,TimePeriod,ContributorName,ContributorContactEmail,TypeofTesting,PrimaryLanguage,Region,Industry,Retest
100,79,4,2024,ToolVendor,Email,Tools,Java,Asia,Software,F
100,862,60,2024,ToolVendor,Email,Tools,Java,Asia,Software,F
100,209,10,2024,ToolVendor,Email,Tools,Java,Asia,Software,F
50,79,25,2024,ManualShop,Email,TaH,Java,Asia,Software,F
50,862,20,2024,ManualShop,Email,TaH,Java,Asia,Software,F
50,209,5,2024,ManualShop,Email,TaH,Java,Asia,Software,F
 
=== per-CWE summary ===
CWE instances(total) apps_with(total) max_rate avg_rate
CWE-79 4025 29 50.00% 27.00%
CWE-209 35 15 10.00% 10.00%
CWE-862 80 80 60.00% 50.00%
 
order by total instances (件数合計順) : CWE-79 > CWE-862 > CWE-209
order by avg incidence rate (平均発生率順): CWE-862 > CWE-79 > CWE-209
order by max incidence rate (最大発生率順): CWE-862 > CWE-79 > CWE-209
orders differ (instances vs avg rate): True
orders differ (instances vs max rate): True
python 3.14.6
exit=0

件数では CWE-79 が 4,025 で首位です。しかしその大半は4つのアプリの中の重複で、発生率ではツール側 4%・手動側 50%、平均 27% です。CWE-862 は件数 80 でも、ツール側 60%・手動側 40%、平均 50% で首位になります。発生率は 0x02 の定義どおり提供者ごとに出し、表の列名にならって、提供者ごとの値の最大と平均を取りました。

表の Total Occurrences も件数ではありません。0x02 の定義は Total number of applications found to have the CWEs mapped to a category. です。

✓ ここまでの確認

模擬データで CWE-79 は件数合計 4,025 で首位なのに、平均発生率では CWE-862 より下でした。理由として正しいのはどれですか。

抽象原理

割合を数えても、順位は割合の順ではない

では、表の値を並べれば順位が出るのでしょうか。0x02 は式を公開しています。

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

続けて The calculated scores ranged from 621.60 for the category of Broken Access Control to 271.08 for Memory Management Errors.、さらに This is not a perfect system, but it is valuable for ranking risk categories. と書きます。導入文も This installment of the Top Ten remains data-informed, but not blindly data-driven. です。

調査の役割は、同じ導入文に2通りの書き方があります。Methodology 節は We ranked 12 categories based on the data contributed, and allowed two to be promoted or highlighted by responses from the community survey.、別の節は we only pick eight of the ten categories from the data です。後者は 2021 版とほぼ同文で、2021 版の「8 + 2」は第15期で扱います。両者をつなぐ説明は導入文に無く(確認範囲: 0x00 全文)、ここではどちらとも決めません。A09 は調査で入ったと明記されています。A03 は overwhelmingly voted a top concern とありますが、調査枠で入ったとまでは書かれていません。

具体実物

表の10行を、9列と公開式で並べてみる

各カテゴリのファイルにある Score table の10行を、列ごとに降順・昇順で並べ、公開式でも計算しました(同じ環境、2回実行して同一)。

$ python3 b_sort_score_table.py(生出力の抜粋。先頭の # run 1 の行・CWE 数の節・節見出し・式の行・昇順の行・A02〜X02 の点・導入文照合の節・末尾の python 3.14.6 と exit=0 の行を省略)コマンド出力
cwes desc: A01 A06 A05 A07 A04 A10 A02 A08 A03 A09
max_inc desc: A02 A06 A10 A01 A07 A04 A05 A09 A03 A08 (ties present)
avg_inc desc: A03 A09 A04 A01 A05 A02 A10 A07 A08 A06
max_cov desc: A01 A02 A04 A05 A07 A10 A06 A09 A08 A03 (ties present)
avg_cov desc: A02 A04 A09 A08 A01 A05 A10 A07 A06 A03 (ties present)
exploit desc: A03 A02 A07 A04 A09 A05 A08 A10 A01 A06 (ties present)
impact desc: A03 A08 A07 A05 A06 A02 A04 A01 A10 A09
occ desc: A01 A04 A05 A07 A10 A06 A02 A08 A09 A03
cves desc: A05 A01 A06 A07 A10 A08 A04 A02 A09 A03
published order: A01 A02 A03 A04 A05 A06 A07 A08 A09 A10
columns whose sort reproduces the published order: NONE
A01: pct-as-fraction -> 632.67 pct-as-number -> 30481.17
order by formula score (pct as fraction): A01 A02 A04 A05 A07 A06 A10 A08 A03 A09
equals published order: False
0x02 L89 says: 621.60 (Broken Access Control) ... 271.08 (Memory Management Errors)
computed A01 = 632.67, X02 = 271.16

省いた昇順の行でも公表順は出ません。読み取れるのは3点です。

  1. どの1列で並べても公表順にならない。 A03 は平均発生率が最高なのに3位、A06 は最低で6位です。
  2. 式は公開されているが、表の値を入れても再現しない。 A01 は 632.67 で文書は 621.60。式の順では A06/A07 と A08/A10 も入れ替わります。理由は原文に書かれていません。
  3. 文書自身が not a perfect system と書いている。
✓ ここまでの確認

0x02 に公開された Risk Score の式に、各カテゴリの表の値を入れて計算すると、どうなりましたか。

⇄ 2つを見比べる
具体例 A

A03:2025 Software Supply Chain Failures(3位)

表では平均発生率 5.72% が10項目で最高、出現アプリ数 215,248 は最少、CWE は6つ。公開式の点は 368.84 で9番目です。導入文は調査で圧倒的に票を集めたと書きます。

A03 の Score table(抜粋)表
CWEs Mapped 6
Avg Incidence Rate 5.72%
Total Occurrences 215,248
Total CVEs 11
具体例 B

A01:2025 Broken Access Control(1位)

表では平均発生率 3.74% で10項目の4番目、出現アプリ数 1,839,701 は最多、CWE は上限の40。公開式の点 632.67 も最高ですが、文書の 621.60 とは一致しません。

A01 の Score table(抜粋)表
CWEs Mapped 40
Avg Incidence Rate 3.74%
Total Occurrences 1,839,701
Total CVEs 32,654

発生率が高い A03 が3位、発生率が中ほどの A01 が1位。この並びから、表の数字について何が言えるでしょうか。

どの列が順位を決めているかではなく、どの列でも決まらないことに注目してください。

この章のまとめ

  • Web 2025 が集めたのは 検査したアプリの数と、CWE を1つ以上持っていたアプリの数。提出形式に件数の列は無い。
  • 件数を捨てる理由は、手動は1回、自動は全件書くから。模型でも件数順と発生率順が入れ替わった。
  • 表の Total Occurrences も アプリの数。
  • どの1列でも公表順は出ない。公開式に表の値を入れても再現しない(A01 632.67 と 621.60)。文書自身が not a perfect system と書く。
  • 調査の役割は導入文に 「12 から 2」と「10 のうち 8」の2通り。断定しない。
  • 導入文と表の不一致は 誤記(3.73%・38) と 未追随(5 CWE・248) に分けて読む。

自分の現場で確かめる

読んだだけでは身につきません。手元の環境で実際に見てみてください。

環境:

理解度チェック

読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。

問題 1 / 3正解: 0

Web 2025 の表の Total Occurrences(A01 は 1,839,701)が数えているものはどれですか。

用語集(4語)
発生率 (incidence rate)
ある提供者がその年に検査したアプリのうち、その CWE を持っていたアプリの割合(0x02 L101)。表の Max / Avg が何にわたる最大・平均かは 0x02 に定義が無い(確認範囲: 0x02 の Data Factors 節)。
件数 (frequency)
1つのアプリの中で同じ弱点が何回現れたか。Web 2025 は計算に入れない。手動は1回だけ書く傾向があり、自動ツールは全箇所を書くため、件数は検査の方法で大きく変わる。
カバレッジ (coverage)
全提供者を通じて、その CWE を検査したアプリの割合。発生率がどれだけ当てになるかの目安として使われる。
Risk Score
0x02 に公開された式で求めるカテゴリの点数。最大発生率・最大カバレッジ・CVE 由来の Exploit と Impact・出現アプリ数を重みづけして足す。