Skip to content

Research · AI Engineering Study · June 8, 2026

Security Engineering with AI Pairs

How AI-assisted engineers handle OWASP-class vulnerabilities — by category, by mitigation, by panel review. The disclosures we tracked, the fixes that stuck, and the patterns that fooled both pair and reviewer.

1,341 security tasks · 318 engineers · 22 vulnerability classes
Codritium Research

Why this matters

Security work is where the AI pair earns or loses its keep. The bugs are quiet, the regressions are expensive, and the reviewer pool is small. Most published numbers on AI-assisted security come from synthetic CTF benchmarks or static-analysis pass rates. Both miss the question that hiring managers actually ask: when an engineer sits down with an AI pair to ship a fix for an authentication bypass on a production-shaped codebase, what happens?

We track that. Every session on the platform records the suggestion graph, the diff, the panel verdict, and the 30-day post-merge outcome. This piece pulls the security-only slice out of the 2026 benchmark. The earlier taxonomy of where the AI pair fails covered all twelve bug classes; here we narrow to the eight that touched the OWASP Top 10 and look at the full lifecycle from suggestion to verified fix.

The lens matters. A coverage-driven view of AI-assisted security work would tell you which categories the AI pair can solve. We are asking a different question — which categories slip through, where in the lifecycle, and how durable the fix is once it is shipped. That framing is closer to what a security lead actually has to answer at quarterly review.

Methodology in one paragraph

A task counts if it is tagged at authoring time as a security challenge — auth, authz, injection, deserialization, SSRF, secrets handling, dependency, or insecure default — and is scored on the v2.6 rubric. We include 1,341 such sessions across 318 engineers between October 2025 and May 2026. Bugs counted here either shipped through the AI-assisted leg of a paired session and were caught by post-merge canaries, panel review, or a dependent test inside 30 days. We exclude tasks where the candidate explicitly disabled the AI pair, and tasks where the post-merge window did not complete by the cutoff. Severity is assigned by the panel using CVSS-aligned guidance, then reviewed by a second rater on disagreement. Inter-rater agreement on severity is 0.79 Krippendorff's α.

847

Distinct vulns shipped

Across the 1,341 sessions

36h

Median disclosure-to-fix

All severities pooled

9/10

OWASP categories seen

Insecure design under-represented

11.4%

Panel false-positive rate

Flagged but not exploitable

Which OWASP categories actually show up

Distribution is uneven. The Top 10 is a long-running list, but on a working codebase only a handful of categories generate real volume. Broken access control and injection together account for more than half of every vuln we saw. Cryptographic failures sit lower than industry surveys suggest — partly because the platform does not yet score key-rotation or TLS-misconfig tasks well, partly because most engineers reach for vetted libraries here and the AI pair rarely introduces a fresh crypto bug.

Share of OWASP Top-10 categories across 847 shipped vulnerabilities.A06 (vulnerable components) and A09 (logging) excluded — see caveats

The heatmap below adds the experience axis. The pattern is the one we expected and also the one that should not console anyone: junior engineers ship more broken-access-control bugs in absolute terms, but per-task incident rate on injection drops only modestly between junior and staff. The AI pair narrows the experience gap on injection because most injection patterns are stale and well-documented in training data; it widens the gap on access control because authorization boundaries are codebase-specific and the model invents plausible-looking checks.

A01A03A07A04A08A02A05A10
Junior
24.1%
18.6%
12.8%
9.4%
7.1%
5.8%
4.6%
3.4%
Mid
18.7%
15.1%
10.2%
8.7%
6.2%
4.9%
4.1%
2.9%
Senior
12.4%
11.8%
7.3%
6.4%
4.8%
3.8%
3.1%
2.2%
Staff
8.1%
9.4%
4.4%
4.1%
2.9%
2.4%
1.9%
1.4%
Per-task incident rate by experience band × OWASP category.n=1,341 sessions · share of tasks introducing ≥1 vuln in class

Where vulns get caught — and where they leak

We instrument every session through a six-stage funnel from suggestion to verification. The interesting cliff is not at the top. AI suggests far more security-adjacent code than ever ships; engineers reject roughly two thirds of it. The real loss happens between "detected" and "triaged" — flagged issues that sit in the queue long enough that a follow-on commit either obscures the root cause or ships a partial fix that closes the visible symptom without removing the vulnerability.

Suggested by AI4218Shipped in diff1492 · 35.4% keptDetected post-merge1186 · 79.5% keptTriaged within SLA921 · 77.7% keptFixed847 · 92.0% keptVerified at 30d798 · 94.2% kept
The security-vuln lifecycle, six stages.n=1,341 sessions · suggestions counted at session close

Two notes on reading this chart. The drop from "suggested" to "shipped" is healthy; it is the engineer doing the work the platform is meant to train them to do. The drop from "fixed" to "verified at 30d" is the failure mode we care most about — 49 vulns we believed fixed regressed within the window. Half of those regressions involved the same engineer revisiting the same module within ten days and accepting an AI suggestion that reverted the fix's intent. That is not a vulnerability problem. It is a context-window problem.

The gap between "detected" and "triaged" deserves its own pass. We mark a finding triaged when an owner has confirmed it, classified it, and accepted the SLA clock. The 265 findings that did not clear triage within SLA were not all ignored — most of them were re-detected on a later commit and re-triaged. The cost of the missed first triage is silent, though. A finding that lingers untriaged for two weeks generates an average of 1.8 follow-on patches in the same module, and 22% of those patches make the original finding harder to reproduce. The detection signal degrades quietly.

Time-to-fix, split by severity

Severity gradient on the time-to-fix curve is sharp at the head and shallow at the tail. P0 vulns close in hours because they trigger the on-call rotation. P1 vulns close in days because they have a fix-by date but no pager. P2 and P3 sit and rot. The stacked area chart traces the disclosure-to-fix time across eight quarters; the long tail at the bottom is mostly P3 vulns that get superseded by refactors before anyone closes them as fixed.

Median disclosure-to-fix time, layered by severity, eight quarters.P3 reflects unbounded open queue, capped at quarter end

The P0 and P1 layers have been shrinking steadily, which is the answer we want. The P3 layer growing is not. Most P3 vulns are defense-in-depth fixes — header tightening, additional rate-limit clauses, secondary validation. None are exploit-by-themselves dangerous; all of them are the work that quietly stops being done when the team is busy. We are starting to track P3 separately in the next reporting cycle.

Mitigation half-life

A fix that does not stick is worse than no fix. It teaches the codebase that the bug was handled, and it makes the next reviewer trust the file. The boxplot below shows 30-day regression rate by vulnerability class — the share of "fixed" cases that regressed inside the window. The whiskers are wide because module-specific factors dominate. The medians are the story.

30-day regression rate2%13%25%37%48%A01 AccessA03 InjectionA07 AuthA04 DesignA08 IntegrityA02 CryptoA05 MisconfigA10 SSRF
Distribution of 30-day regression rate, by OWASP class.n=798 verified fixes · regression = same class shipped on same module

Injection fixes hold. Crypto fixes hold. Access-control fixes break, and insecure-design fixes break worst of all. The reason is structural — injection has a sharp test (does the parameter reach a sink?) while access control has a fuzzy test (is this caller permitted, in this context, given this resource ownership?). The AI pair codifies the fuzzy test as a conditional that reads the way an example in training data reads. Three commits later, an unrelated change adds a code path that bypasses the condition, and nobody on the team treats the original fix as load-bearing.

Detection cost is not remediation cost

We expected detection and remediation cost to correlate. They do not. The quadrant chart plots OWASP categories on two axes: how expensive it is to find an instance (panel hours per detection) and how expensive it is to fix it once found (engineer hours per fix). The four quadrants tell different stories.

Hard detect / hard fixEasy detect / hard fixHard detect / easy fixEasy detect / easy fixDetection cost (panel hours per finding)Remediation cost (engineer hours per fix)010016A04 DesignA01 AccessA07 AuthA10 SSRFA05 MisconfigA08 IntegrityA03 InjectionA02 Crypto
OWASP categories on detection × remediation cost.Median across 1,341 sessions · in panel/engineer hours

Insecure design sits alone in the worst quadrant. It is the work nobody wants because there is no checklist for it. Injection and cryptographic failures sit in the cheapest quadrant because both the detection signal (static patterns) and the remediation (replace the unsafe call with the vetted one) are well-rehearsed. Authorization is the surprising case — cheap-ish to detect once you build the harness, expensive to fix because every fix needs a regression test that exercises the role matrix. Teams that under-invest in their authorization test fixture pay this cost every release.

The patterns that keep showing up

Ten code-shaped patterns generate 41% of all OWASP-class bugs we observed. The trend column shows how the pattern's relative share has moved across six quarters; the upticks are usually a new SDK release encouraging the pattern, and the downticks are usually a reviewer cohort getting trained against it.

#PatternModal classShare6-Q trend
1Permission check inside business logicA01 Access8.4%
2Parameter passed to raw-SQL helperA03 Injection6.7%
3Session token in URL queryA07 Auth5.1%
4Trusted-by-default internal endpointA01 Access4.6%
5Untyped JSON body to ORMA08 Integrity4.2%
6Reflected error message with stackA05 Misconfig3.8%
7OAuth state regenerated per retryA07 Auth3.1%
8URL fetched from user-controlled fieldA10 SSRF2.4%
9Secret in env var read at runtime in handlerA02 Crypto1.9%
10Role check delegated to callerA04 Design1.8%
Top-10 high-yield security patterns.n=847 vulns · trend = share of class per quarter, last six quarters

The upward trends are mostly the cost of new framework conventions outpacing the reviewer cohort. The downward trends are real wins, particularly raw-SQL helpers — the panel started flagging these as a red-card pattern eighteen months ago and adoption of the safer interface has followed. We expect "permission check inside business logic" to peak in the next two quarters as authorization tooling matures, then start to decline.

A note on what is missing from this list. Memory-safety bugs do not appear because the platform's challenge bank is currently weighted toward managed-runtime languages. Side-channel and timing patterns do not appear because we cannot reliably score them in a 30-day window. Supply-chain patterns — typosquatted packages, prompt-injected install scripts — are tracked separately and we will publish them in a companion piece. Treat the table as a partial map, not a complete one.

Caveats

Panel review cannot catch what it does not see. Two OWASP categories — A06 (vulnerable components) and A09 (logging failures) — are under-instrumented in our task set and therefore under-counted here; the donut and heatmap reflect what got measured, not what is out there. The engineer sample is self-selected — these are people who chose security challenges, so they are warmer to security work than the population they came from, and the per-task incident rates likely underestimate what a generalist team would ship. This is observational, not randomized; we do not have a true control arm where the same engineer solves the same task without the AI pair. Severity assignment by the panel is consistent (α = 0.79) but not infallible, and our 11.4% false-positive rate is itself a panel-judged number, with all the circularity that implies. Finally, the 30-day post-merge window catches what regresses fast and misses what regresses slowly; the access-control regression rate in particular is probably a floor.

What we'll do next

We re-run this study every six months. The next cut adds three classes we currently miss — log-injection patterns, prototype pollution, and CSP regression — and switches from a 30-day to a 60-day post-merge window for access-control fixes only, where the regression tail clearly extends past 30 days. The session-level data behind this report is available for replication; the methodology, panel calibration set, and severity guidance are versioned in the public rubric. Independent teams who want to reproduce the funnel on their own challenge bank can use our task tagging schema as a starting point. Questions, corrections, and replication attempts are welcome.