LLM triage on the OWASP Benchmark sample

Model gemini:gemini-3.1-flash-lite, temperature 0.3. 450 Benchmark cases (stratified sample, Java), 388 findings triaged per run. Only confident false positives are dropped.

In plain English: precision is how many flagged issues are real; recall is how many real issues get found; false-positive rate is how many safe code samples are wrongly flagged. Higher precision and recall are better; lower false-positive rate is better.

ConfigurationPrecisionRecallFPRYouden
A. Opengrep (sast-rules) 0.6750.6000.2890.311
B. A + custom rules 0.6760.8890.4270.462
C. B + LLM triage (1 run) 0.7120.8890.3600.529
00.51 A. Opengrep (sast-rules): 0.675 0.68 A B. A + custom rules: 0.676 0.68 B C. B + LLM triage (1 run): 0.712 0.71 C Precision (higher is better) A. Opengrep (sast-rules): 0.600 0.60 A B. A + custom rules: 0.889 0.89 B C. B + LLM triage (1 run): 0.889 0.89 C Recall (higher is better) A. Opengrep (sast-rules): 0.289 0.29 A B. A + custom rules: 0.427 0.43 B C. B + LLM triage (1 run): 0.360 0.36 C False-positive rate (lower is better)

A. Opengrep (sast-rules)B. A + custom rulesC. B + LLM triage (1 run)

Per Benchmark category (precision / recall / FPR)

The OWASP column comes from owasp_2025.yaml, checked against the official OWASP Top 10 2025 CWE lists. Each cell rests on about 20 real and 20 fake cases.

CategoryOWASP 2025A. Opengrep (sast-rules)B. A + custom rulesC. B + LLM triage (1 run)
cmdiA05 0.60 / 1.00 / 0.670.60 / 1.00 / 0.670.62 / 1.00 / 0.62
cryptoA04 0.82 / 0.86 / 0.190.82 / 0.86 / 0.190.82 / 0.86 / 0.19
hashA04 1.00 / 0.76 / 0.001.00 / 0.76 / 0.001.00 / 0.76 / 0.00
ldapiA05 0.54 / 1.00 / 0.860.54 / 1.00 / 0.860.54 / 1.00 / 0.86
pathtraverA01 0.57 / 1.00 / 0.760.57 / 1.00 / 0.760.58 / 1.00 / 0.71
securecookieA02 1.00 / 1.00 / 0.001.00 / 1.00 / 0.001.00 / 1.00 / 0.00
sqliA05 n/a / 0.00 / 0.000.61 / 0.52 / 0.330.69 / 0.52 / 0.24
trustboundA06 n/a / 0.00 / 0.000.58 / 0.90 / 0.670.63 / 0.90 / 0.52
weakrandA04 n/a / 0.00 / 0.000.88 / 1.00 / 0.140.95 / 1.00 / 0.05
xpathiA05 n/a / 0.00 / 0.000.67 / 0.93 / 0.470.67 / 0.93 / 0.47
xssA05 0.57 / 0.81 / 0.620.57 / 0.81 / 0.620.71 / 0.81 / 0.33
overall 0.68 / 0.60 / 0.290.68 / 0.89 / 0.430.71 / 0.89 / 0.36

Limits

Baseline on the full OWASP Benchmark

Opengrep + GitLab sast-rules, no LLM. 2740 cases, 1579 findings. Precision and recall are shown only where ground truth exists.

Full Benchmark

CategoryTPFPTNFNPrecisionRecallFPRYouden
cmdi12694310 0.571.000.750.25
crypto105278925 0.800.810.230.57
hash89010740 1.000.690.000.69
ldapi272750 0.501.000.840.16
pathtraver127115206 0.520.950.850.10
securecookie360310 1.001.000.001.00
sqli00232272 n/a0.000.000.00
trustbound004383 n/a0.000.000.00
weakrand00275218 n/a0.000.000.00
xpathi002015 n/a0.000.000.00
xss1821189164 0.610.740.560.18
overall692381944723 0.640.490.290.20

450-case sample

CategoryTPFPTNFNPrecisionRecallFPRYouden
cmdi211470 0.601.000.670.33
crypto184173 0.820.860.190.67
hash160215 1.000.760.000.76
ldapi211830 0.541.000.860.14
pathtraver211650 0.571.000.760.24
securecookie210210 1.001.000.001.00
sqli002121 n/a0.000.000.00
trustbound002121 n/a0.000.000.00
weakrand002121 n/a0.000.000.00
xpathi001515 n/a0.000.000.00
xss171384 0.570.810.620.19
overall1356516090 0.680.600.290.31

Benchmark categories with no rule coverage

sqli, trustbound, weakrand, xpathi

OWASP Top 10 2025 coverage

IDCategoryStatusCases
A01Broken Access Control Measured268
A02Security Misconfiguration Measured67
A03Software Supply Chain Failures Not covered0
A04Cryptographic Failures Measured975
A05Injection Measured1304
A06Insecure Design Measured126
A07Authentication Failures Not covered0
A08Software or Data Integrity Failures Not covered0
A09Security Logging and Alerting Failures Not covered0
A10Mishandling of Exceptional Conditions Not covered0

"Measured" means ground truth exists for at least one CWE in that category, not that the whole category is tested. "Not covered" categories have no metrics.