Mind the Gap: Do Widely-used SAST Tools Really Cover the Language-Specific Top CWEs?

A large-scale empirical study on the coverage of 9 popular SAST tools across C/C++, Java, and Python, evaluated against language-specific Top CWE lists derived from 197,016 CVEs over the past 10 years.

197,016
CVEs Analyzed
944
CWE Types
9
SAST Tools
3
Languages
RQ1

Language-Specific Distribution of Top CWEs

What is the language-specific distribution of top CWEs in real-world vulnerabilities across C/C++, Java, and Python?

CVE Trends (2016–2025)

C/C++

205
Top CWEs
37,887
CVEs
116
Covered

Java

123
Top CWEs
6,703
CVEs
97
Covered

Python

86
Top CWEs
1,915
CVEs
74
Covered

Root CWE Distribution by Language

Percentage of CVEs across the 10 root CWE categories in CWE View 1000

Finding 1: Across all three languages, CWE-664 (Improper Control of a Resource Through its Lifetime) and CWE-707 (Improper Neutralization) are the most frequent root CWE categories. The third most frequent varies: for C/C++ it is CWE-710 (Improper Adherence to Coding Standard), whereas for Java and Python it is CWE-284 (Improper Access Control).

Language-Specific vs. General CWE Top 25

Comparing language-specific Top 25 CWEs with the general CWE Top 25 benchmark

Jaccard Similarity set-level overlap

RBO (q=0.9) rank-aware similarity

Top 25 CWE Lists — Side by Side

TopC/C++ 25

TopC/C++ 25 (CVSS)

TopJava 25

TopJava 25 (CVSS)

TopPython 25

TopPython 25 (CVSS)

Cross-Comparison Similarity Matrix

C/C++C/C++ (CVSS)JavaJava (CVSS)PythonPython (CVSS)NIST
C/C++
Jaccard
10.670.110.160.160.160.32
C/C++ (CVSS)
Jaccard
0.6710.190.220.220.220.43
Java
Jaccard
0.110.1910.560.470.430.35
Java (CVSS)
Jaccard
0.160.220.5610.470.560.39
Python
Jaccard
0.160.220.470.4710.560.28
Python (CVSS)
Jaccard
0.160.220.430.560.5610.32
NIST
Jaccard
0.320.430.350.390.280.321
C/C++C/C++ (CVSS)JavaJava (CVSS)PythonPython (CVSS)NIST
C/C++
RBO (q=0.9)
10.550.040.070.020.060.17
C/C++ (CVSS)
RBO (q=0.9)
0.5510.020.050.070.070.19
Java
RBO (q=0.9)
0.040.0210.620.290.380.54
Java (CVSS)
RBO (q=0.9)
0.070.050.6210.390.560.41
Python
RBO (q=0.9)
0.020.070.290.3910.590.14
Python (CVSS)
RBO (q=0.9)
0.060.070.380.560.5910.19
NIST
RBO (q=0.9)
0.170.190.540.410.140.191
Finding 2: The language-specific Top CWE lists differ substantially from the general CWE Top 25 — RBO scores for TopC/C++ (0.17) and TopPython (0.14) against the general list do not exceed 0.2. Java aligns more closely (RBO = 0.54), suggesting the general ranking is biased toward Java.
RQ2

Top CWE Coverage Gaps in SAST Tools

To what extent are top CWEs covered by existing SAST tools, and what causes non-coverage?

Overall Coverage

C/C++

56.59%
116 / 205 Top CWEs Covered

Java

78.86%
97 / 123 Top CWEs Covered

Python

86.05%
74 / 86 Top CWEs Covered

Coverage by Root CWE Category per Language

Finding 3: The whole SAST tool set shows low coverage of the TopLan CWE list. C/C++ is the lowest at 56.59%. Enhancing C/C++ detection must be a critical priority.

Uncovered High-Frequency CWEs — Detailed View

C/C++ Java Python

C/C++ Missed (65)

Java Missed (17)

Python Missed (9)

Why Are These CWEs Uncovered?

Four categories of reasons for non-coverage by SAST tools

Reason Breakdown by Language

Classification Categories

① Dynamic Data Value Dependence

Vulnerabilities depending on runtime variable values, computation results, or memory states that SAST tools cannot reliably predict.

② Project Configuration & Environment Dependence

Vulnerabilities tied to project-specific business logic, security policies, and unique factors such as industry standards or system configurations.

③ System Timing & Hardware Interaction Dependence

Vulnerabilities stemming from thread scheduling, event ordering, and physical/hardware states that static analysis cannot model.

④ Complex Input & Sequence Dependence

Vulnerabilities triggered by specific external inputs or event sequences that static analysis cannot exhaustively examine.

Uncovered CWE Reason Counts

LanguageDynamic Data ValueProject Config & EnvironmentSystem Timing & HardwareComplex Input & SequenceTotal
C/C++103171765
Java464317
Python31329
Finding 4: Missed top CWEs occur primarily in C/C++. Project Configuration and Environment Dependence accounts for the largest share. About 60% of these gaps can be addressed by hybrid methods (LLMs + runtime info), while timing and complex input dependencies remain largely unresolved.

Uncovered CWEs with Reason Classification

Uncovered CWEs per language and their reason categories

CWE-IDNameClassification
RQ3

CWE Coverage Variation Across SAST Tools

What differences exist in coverage across different SAST tools, and how do multi-language tools cover shared top CWEs?

Coverage by Tool per Language

Top CWE Coverage by Tool

Tool Coverage Details

LanguageToolCovered CWEsCovered Top CWEsCoverage %Tool-Only Top CWEsTool-Only CWEs
C/C++CodeQL15610852.68%4577
Cppcheck523416.59%28
Semgrep282210.73%23
CSA24178.29%15
Flawfinder474019.51%34
JavaCodeQL2209274.80%1271
SonarQube1426149.59%427
SpotBugs1066552.85%117
Semgrep775746.34%02
Insider443629.27%01
PythonCodeQL1376777.91%636
Semgrep896069.77%415
SonarQube924754.65%013
Bandit453641.86%26

Tool-Only CWE Details

CWE IDs unique to each tool (not covered by any other tool in the same language)

CodeQL — Tool-Only Top CWEs (45)

CWE-23, CWE-73, CWE-79, CWE-88, CWE-89, CWE-121, CWE-122, CWE-129, CWE-191, CWE-193, CWE-228, CWE-252, CWE-266, CWE-271, CWE-273, CWE-287, CWE-290, CWE-295, CWE-311, CWE-312, CWE-319, CWE-326, CWE-345, CWE-359, CWE-369, CWE-401, CWE-405, CWE-428, CWE-497, CWE-522, CWE-610, CWE-611, CWE-642, CWE-772, CWE-789, CWE-805, CWE-823, CWE-835, CWE-843, CWE-909, CWE-922, CWE-943, CWE-1023, CWE-1285, CWE-1390

CodeQL — Tool-Only CWEs (77)

CWE-23, CWE-36, CWE-73, CWE-79, CWE-88, CWE-89, CWE-114, CWE-121, CWE-122, CWE-128, CWE-129, CWE-170, CWE-191, CWE-192, CWE-193, CWE-228, CWE-233, CWE-234, CWE-243, CWE-252, CWE-253, CWE-260, CWE-266, CWE-271, CWE-273, CWE-287, CWE-290, CWE-295, CWE-311, CWE-312, CWE-313, CWE-319, CWE-326, CWE-345, CWE-359, CWE-369, CWE-390, CWE-401, CWE-405, CWE-409, CWE-428, CWE-456, CWE-468, CWE-478, CWE-481, CWE-482, CWE-497, CWE-522, CWE-546, CWE-560, CWE-561, CWE-610, CWE-611, CWE-642, CWE-685, CWE-686, CWE-687, CWE-764, CWE-772, CWE-775, CWE-789, CWE-805, CWE-823, CWE-826, CWE-835, CWE-843, CWE-909, CWE-922, CWE-943, CWE-1023, CWE-1041, CWE-1076, CWE-1078, CWE-1126, CWE-1240, CWE-1285, CWE-1390

Cppcheck — Tool-Only Top CWEs (2)

CWE-763, CWE-786

Cppcheck — Tool-Only CWEs (8)

CWE-195, CWE-571, CWE-590, CWE-688, CWE-762, CWE-763, CWE-786, CWE-910

Semgrep Top (2)

CWE-532, CWE-538

Semgrep All (3)

CWE-532, CWE-538, CWE-774

CSA Top (1)

CWE-338

CSA All (5)

CWE-338, CWE-466, CWE-469, CWE-477, CWE-588

Flawfinder — Tool-Only Top CWEs (3)

CWE-250, CWE-657, CWE-829

Flawfinder — Tool-Only CWEs (4)

CWE-250, CWE-657, CWE-785, CWE-829
Finding 5: The covered TopLan CWE sets vary substantially across tools. CodeQL achieves the highest coverage across all languages (≈3.6× the lowest-performing tool). No single tool covers all CWEs — practitioners should combine tools based on target CWE categories.

Checker Migration Across Languages

For top CWEs shared across languages, can existing checkers be migrated to other languages?

CodeQL — Missing & Migratable

Semgrep — Missing & Migratable

Migration Feasibility — Fine-Grained Classification

CodeQL

LanguageDirect RuleQuery-onlySemantically Non-Migr.Prohibitive Lib
C/C++211579
Java11143
Python0085

Semgrep

LanguageDirect RuleQuery-onlySemantically Non-Migr.Prohibitive Lib
C/C++394382
Java1100
Python0100

Checker Migration Details

Per-checker migration feasibility across languages — grouped by tool and source language

DR — Direct Rule Migration : denotes rule reuse without synonymous structural substitution — i.e., rule-level migration.
QO — Query-only Migration : requires only rewriting queries without expanding libraries — i.e., checker-level migration.
Migratable 0 Semantically Non-Migr. 0 Prohibitive Lib 0
Migratable 0 Semantically Non-Migr. 0 Prohibitive Lib 0
Finding 6: About 75% of checkers can be migrated. C/C++ has the most migratable checkers. Semgrep (92.5% migration rate) shows higher transferability than CodeQL (47.7%), suggesting pattern-based checkers are easier to migrate than semantically complex ones.