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.
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++
Java
Python
Root CWE Distribution by Language
Percentage of CVEs across the 10 root CWE categories in CWE View 1000
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) | Java | Java (CVSS) | Python | Python (CVSS) | NIST | |
|---|---|---|---|---|---|---|---|
| C/C++ Jaccard | 1 | 0.67 | 0.11 | 0.16 | 0.16 | 0.16 | 0.32 |
| C/C++ (CVSS) Jaccard | 0.67 | 1 | 0.19 | 0.22 | 0.22 | 0.22 | 0.43 |
| Java Jaccard | 0.11 | 0.19 | 1 | 0.56 | 0.47 | 0.43 | 0.35 |
| Java (CVSS) Jaccard | 0.16 | 0.22 | 0.56 | 1 | 0.47 | 0.56 | 0.39 |
| Python Jaccard | 0.16 | 0.22 | 0.47 | 0.47 | 1 | 0.56 | 0.28 |
| Python (CVSS) Jaccard | 0.16 | 0.22 | 0.43 | 0.56 | 0.56 | 1 | 0.32 |
| NIST Jaccard | 0.32 | 0.43 | 0.35 | 0.39 | 0.28 | 0.32 | 1 |
| C/C++ | C/C++ (CVSS) | Java | Java (CVSS) | Python | Python (CVSS) | NIST | |
|---|---|---|---|---|---|---|---|
| C/C++ RBO (q=0.9) | 1 | 0.55 | 0.04 | 0.07 | 0.02 | 0.06 | 0.17 |
| C/C++ (CVSS) RBO (q=0.9) | 0.55 | 1 | 0.02 | 0.05 | 0.07 | 0.07 | 0.19 |
| Java RBO (q=0.9) | 0.04 | 0.02 | 1 | 0.62 | 0.29 | 0.38 | 0.54 |
| Java (CVSS) RBO (q=0.9) | 0.07 | 0.05 | 0.62 | 1 | 0.39 | 0.56 | 0.41 |
| Python RBO (q=0.9) | 0.02 | 0.07 | 0.29 | 0.39 | 1 | 0.59 | 0.14 |
| Python (CVSS) RBO (q=0.9) | 0.06 | 0.07 | 0.38 | 0.56 | 0.59 | 1 | 0.19 |
| NIST RBO (q=0.9) | 0.17 | 0.19 | 0.54 | 0.41 | 0.14 | 0.19 | 1 |
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++
Java
Python
Coverage by Root CWE Category per Language
Uncovered High-Frequency CWEs — Detailed View
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
Vulnerabilities depending on runtime variable values, computation results, or memory states that SAST tools cannot reliably predict.
Vulnerabilities tied to project-specific business logic, security policies, and unique factors such as industry standards or system configurations.
Vulnerabilities stemming from thread scheduling, event ordering, and physical/hardware states that static analysis cannot model.
Vulnerabilities triggered by specific external inputs or event sequences that static analysis cannot exhaustively examine.
Uncovered CWE Reason Counts
| Language | Dynamic Data Value | Project Config & Environment | System Timing & Hardware | Complex Input & Sequence | Total |
|---|---|---|---|---|---|
| C/C++ | 10 | 31 | 7 | 17 | 65 |
| Java | 4 | 6 | 4 | 3 | 17 |
| Python | 3 | 1 | 3 | 2 | 9 |
Uncovered CWEs with Reason Classification
Uncovered CWEs per language and their reason categories
| CWE-ID | Name | Classification |
|---|
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
| Language | Tool | Covered CWEs | Covered Top CWEs | Coverage % | Tool-Only Top CWEs | Tool-Only CWEs |
|---|---|---|---|---|---|---|
| C/C++ | CodeQL | 156 | 108 | 52.68% | 45 | 77 |
| Cppcheck | 52 | 34 | 16.59% | 2 | 8 | |
| Semgrep | 28 | 22 | 10.73% | 2 | 3 | |
| CSA | 24 | 17 | 8.29% | 1 | 5 | |
| Flawfinder | 47 | 40 | 19.51% | 3 | 4 | |
| Java | CodeQL | 220 | 92 | 74.80% | 12 | 71 |
| SonarQube | 142 | 61 | 49.59% | 4 | 27 | |
| SpotBugs | 106 | 65 | 52.85% | 1 | 17 | |
| Semgrep | 77 | 57 | 46.34% | 0 | 2 | |
| Insider | 44 | 36 | 29.27% | 0 | 1 | |
| Python | CodeQL | 137 | 67 | 77.91% | 6 | 36 |
| Semgrep | 89 | 60 | 69.77% | 4 | 15 | |
| SonarQube | 92 | 47 | 54.65% | 0 | 13 | |
| Bandit | 45 | 36 | 41.86% | 2 | 6 |
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)
CodeQL — Tool-Only CWEs (77)
Cppcheck — Tool-Only Top CWEs (2)
Cppcheck — Tool-Only CWEs (8)
Semgrep Top (2)
Semgrep All (3)
CSA Top (1)
CSA All (5)
Flawfinder — Tool-Only Top CWEs (3)
Flawfinder — Tool-Only CWEs (4)
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
| Language | Direct Rule | Query-only | Semantically Non-Migr. | Prohibitive Lib |
|---|---|---|---|---|
| C/C++ | 21 | 15 | 7 | 9 |
| Java | 1 | 1 | 14 | 3 |
| Python | 0 | 0 | 8 | 5 |
Semgrep
| Language | Direct Rule | Query-only | Semantically Non-Migr. | Prohibitive Lib |
|---|---|---|---|---|
| C/C++ | 39 | 43 | 8 | 2 |
| Java | 1 | 1 | 0 | 0 |
| Python | 0 | 1 | 0 | 0 |
Checker Migration Details
Per-checker migration feasibility across languages — grouped by tool and source language