Insight

Does a multi-model pipeline make AI-generated code more secure?

What generating the same spec with three different models actually buys you, across seven 2026 benchmarks. Three models catch each other’s quirks. All three ship the same IDOR.

Does a multi-model pipeline make AI-generated code more secure?

Generating the same thing with several models and comparing the results is a real practice, and it’s well documented. Addy Osmani’s 2026 workflow post suggests trying “two or more LLMs in parallel to cross-check how they might approach the same problem differently.” A widely shared DEV writeup calls it the Comparison Pattern and gets specific: “Run it through three different models simultaneously. I use Claude Opus 4.6, GPT-5.4, and Gemini 3.1 Pro side by side.” Cursor’s forum has a standing request to automate the whole loop. There’s an academic version too: EnsLLM collects candidates from several LLMs and uses similarity scoring and a voting step to pick the one they agree on most, and it beats the best single model on HumanEval, 90.2% against 83.5%.

Read those sources closely and every one of them is making a correctness argument. Osmani’s is about what to do when a model gets stuck. The Comparison Pattern tells you to dig into the disagreements: “When the models diverge, that’s your signal to dig deeper.” EnsLLM measures functional accuracy on coding benchmarks.

The leap is what happens next. If three models agreeing produces more correct code, surely it produces safer code. Independent models fail independently, so pooling three of them should leave less behind than one. If that holds, generating three times is the cheapest security control anyone has proposed: a few dollars of API credits against a class of bug that gets companies breached.

So I went through the 2026 generation benchmarks. Seven of them, plus the handful of papers published since March that finally measure the pooling instead of reasoning about it.

It does not hold, and the way it fails is specific.

Here’s the summary before the evidence. Three models will catch each other’s quirks: this one’s eval(), that one’s debug flag, the third one’s stale dependency. None of them will catch the bug that actually gets you owned, because every model on the market fails that one in exactly the same way. The chart below is the whole argument, and the rest of this post is me showing my work.

CWEWEAKNESSSHARE OF GENERATED BUILDS THAT SHIPPED ITSEVERITYTHREE MODELS BUY YOU NOTHINGEvery model fails these the same way. This is the set you own.CWE-639/862Broken access control (IDOR)100%CRITICALCWE-918SSRF100%CRITICALCWE-770No rate limiting93%HIGHCWE-117Log injection88%MEDIUMMULTI-MODEL CATCHES PART OF ITRate and style differ between models, so the diff is worth reading.CWE-489/215Active debug code100%MEDIUMCWE-80XSS at the sink85%HIGHCWE-22/23Path traversal70%*HIGHCWE-613/347Token revocation67%HIGHCWE-798Secret default fallback46%CRITICALCWE-502Insecure deserialization40%*CRITICALTHE MODELS ALREADY HANDLE THESEA clear local rule, well represented in training data.CWE-89SQL injection17%n/aCWE-327Broken crypto13%n/a0255075100* positioned from qualitative verdicts, no single source reports a rate
Twelve weaknesses, ranked by the share of generated builds that shipped them and grouped by what generating with more models actually buys you. Bars marked * are positioned from qualitative verdicts because no single source reports a rate; every other bar carries its own study and denominator, listed in the sections below. Severity is the deployed-app severity from arXiv:2606.23130.

Two questions, and I want to be precise about them. When you hand the same spec to different models, do they introduce different kinds of bugs? And if they do, does generating three times and reading the diff cut your residual risk enough to be worth doing?

Three different questions keep getting mixed up

“AI-generated code security” gets muddled because three different questions travel under the same label. I keep them separate throughout, because they have different answers.

Layer Unit Studies
L1: snippet generation One function or endpoint, identical prompt across models AppSecSanta (522 samples, 6 models), Veracode (100+ models, 80 tasks)
L2: agent and full-app generation A whole application, or a feature inside a real repository Armis (18 models × 31 scenarios), SusVibes (12 agentic settings, 186 tasks), Datadog (3 models × 2 modes), Tenzai (5 agents, 15 apps)
L3: deployed applications Production apps, found by agent fingerprints arXiv:2606.23130 (200 deployed apps, 1,471 vulnerabilities), Escape, Vibe App Scanner, CVE-2025-48757

One exclusion up front: I only cite generation benchmarks (does the model emit vulnerable code?). Detection benchmarks (can a scanner find an existing bug?) are a different measurement and are not comparable. This post is also not about the OWASP GenAI LLM Top 10: prompt injection and agent risks are risks to LLM applications. This is about risks from the code the models emit.

Same prompt, six models

AppSecSanta sent 87 identical prompts (login forms, file uploads, database queries, no security guidance) to six models via a single API endpoint at temperature 0, then scanned all 522 outputs with five SAST tools and hand-validated every finding. 926 raw findings reduced to 154 confirmed true positives.

25.7% of samples contained at least one confirmed vulnerability. Here is the full matrix:

Model Vuln rate A01 access control A05 injection A07 auth A10/debug SSRF (CWE-918) Python / JS
GPT-5.2 19.5% 9 n/a 1 n/a 4 11.6% / 27.3%
Grok 4 21.8% 11 2 1 4 n/a 20.9% / 22.7%
Gemini 2.5 Pro 23.0% 11 4 n/a n/a n/a 18.6% / 27.3%
Claude Opus 4.6 29.9% 12 4 n/a 6 n/a 32.6% / 27.3%
DeepSeek V3 29.9% 12 5 n/a 5 n/a 27.9% / 31.8%
Llama 4 Maverick 29.9% 10 4 5 3 n/a 25.6% / 34.1%

n/a means the source’s per-model breakdown does not itemize a count for that cell, not that the model produced zero findings.

Three things stand out.

The rate spread is 10 points; the category spread is nearly zero. Broken Access Control led for every model (9 to 12 findings each). The top CWEs across all models were SSRF (CWE-918, 32 findings), path traversal (CWE-22/23, 30), Flask debug left on (CWE-215/489, 18), insecure deserialization (CWE-502, 14), and NoSQL injection (CWE-943, 10). Five of six models produced 5–6 vulnerable SSRF samples on 8 SSRF prompts; GPT-5.2 produced 4, a gap the author himself places at the noise floor.

The model signatures are real, and they live in the margins. Llama 4 Maverick produced 5 authentication failures (A07) where GPT-5.2 and Grok 4 produced 1 each, with its JavaScript struggling specifically on “authentication token handling and cookie security.” Claude Opus 4.6 produced the most debug-mode findings (A10 = 6) and was the only model whose Python was worse than its JavaScript (32.6% vs 27.3%). DeepSeek V3 had the highest raw count, and its signature is the one people quote: eval(), string-concatenated queries, debug configurations on by default.

Language is a bigger factor than vendor for some models. GPT-5.2 scored 11.6% in Python and 27.3% in JavaScript, a 15.7-point gap within one model. Grok 4 was the most consistent at 1.8 points. Veracode sees the same effect at industry scale: Python 62% pass rate, JavaScript 57%, and Java at 29–30%, the worst language by a wide margin, which they attribute to training data skewed toward legacy Java patterns.

Broken accessA01InjectionA05Auth failuresA07Debug / misconfigA10SSRFCWE-918GPT-5.219.5% vulnerable914Grok 421.8% vulnerable11214Gemini 2.5 Pro23.0% vulnerable114Claude Opus 4.629.9% vulnerable1246DeepSeek V329.9% vulnerable1255Llama 4 Maverick29.9% vulnerable10453
Confirmed findings per model per category. AppSecSanta, 87 identical prompts, 522 samples, five SAST tools, every finding hand-validated. Data collected February 2026, re-audited May 2026. Blank means the source does not itemise a count for that cell, not that the model produced zero. Armis measured a 29-point swing between Gemini 2.5 Pro and Gemini 3.1 Pro one generation apart, so treat any model ranking as stale within a quarter.

The ceiling that has not moved in four years

Veracode has run the most consistent longitudinal study available: 80 tasks, four languages, four CWEs, more than 100 models over four years. The full 2026 report landed on 28 July 2026 and supersedes the Spring update most coverage still quotes. Two numbers define the field.

Syntax correctness has climbed to above 95%. The security pass rate has sat at 55–56% for four years, across more than 100 models, regardless of model size or release date. The 2026 report’s leaderboard shows GPT-5.5 leading at 68%, with six of eleven tested models clustered between 50–53%. Models purpose-built for coding average 51%; general-purpose models average 52%. Being trained to write code faster does not mean writing it safer.

The breakdown by weakness type is more interesting than the overall rate, because it is identical across vendors:

Weakness Pass rate
CWE-327, broken cryptographic algorithms 87%
CWE-89, SQL injection 83%
CWE-80, XSS (output sanitization) 15%
CWE-117, log injection 12%

Veracode’s own diagnosis: models excel at “obvious, surface-level patterns, like parameterized SQL queries,” and fail where the task “requires understanding dataflow across multiple lines or files.” Cross-file dataflow is the part that does not fit in a local pattern match, and the SusVibes numbers further down measure the same wall from the other side: security pass rates fall from 15.4% on single-file tasks to 3.0% once a fix spans more than two files.

One correction on the reasoning-model exception, because the wrong number is in wide circulation. Veracode’s Spring 2026 update put OpenAI’s reasoning models at 70–72%, and that figure travelled as though it described reasoning models generally. The full 2026 report, on a wider sample, puts reasoning models at 56% against 51% for non-reasoning. Five points, not fifteen, and no evidence it is a vendor-independent effect.

Broken cryptoCWE-32787%SQL injectionCWE-8983%XSS, output sanitizationCWE-8015%Log injectionCWE-11712%
Security pass rate by weakness type across more than 100 models. Veracode, 2026 GenAI Code Security Report, 28 July 2026. The persuasion is in the shape: every vendor produces this same curve. When every vendor produces one curve, model choice is not a security decision.

Whole applications make it worse

Snippets understate the problem, because a full application adds architecture, iteration, and deployment decisions on top of the code itself. Three datasets cover this layer, and they converge.

Armis Labs, Trusted Vibing Benchmark (18 models, 31 scenarios, ~90 atomic actions per scenario, scanned with no manual modification of generated code): 100% of models failed to consistently produce secure code. In 18 of 31 scenarios, every single model emitted CWE-bearing code. The named universal blind spots are buffer overflows, design-file-upload, login systems, and unsafe deserialization. The best performer, gemini-3.1-pro, still produced OWASP-grade vulnerabilities in 38.71% of scenarios. The single worst generation in the benchmark came from claude-sonnet-4.5 on a path-traversal-download task: ten distinct vulnerabilities in one output, including active debug code (CWE-489), inadequate access restriction (CWE-284), and unbounded resource allocation (CWE-770).

The same benchmark quantifies two confounders that matter more than model choice. Version drift: gemini-2.5-pro scored 67.74% vulnerable scenarios; gemini-3.1-pro scored 38.71% one generation later, and cut compounding failures from 22.58% to 0.00%. Harness effects: claude-sonnet-4.5 scored 61.29% in the Claude Code harness and 77.42% in OpenCode, a 16-point difference on the same model.

SusVibes (arXiv:2512.03262v3, ICML 2026, revised Aug 2026) is the one study I found carrying a true model × CWE matrix at the repository level: 186 real feature-request tasks mined from actual vulnerability-fix commits, covering 79 CWE types, evaluated with human-written functional and security tests. Twelve agentic settings: three frameworks, four models.

The headline is brutal. The best configuration (SWE-agent + Claude 4 Sonnet) passed functional tests on 57% of tasks, but only 11.8% were both correct and secure. 79.3% of functionally correct solutions contained a vulnerability. On a security-normalized metric (secure share on the tasks all models solved correctly), the ranking is: Gemini 2.5 Pro 30.4%, Kimi K2 22.0%, Gemini 3 Pro 21.4%, Claude 4 Sonnet 18.3%. The framework ranking: SWE-agent 23.3%, OpenHands 20.1%, Claude Code 17.4%.

The skew finding is the relevant one for this post, and SusVibes states it directly: “Agent frameworks and LLMs are cautious in different CWE categories.” Kimi K2 handles cryptographic failures better. Gemini 3 Pro excels at enforcing access control. And within a single category (Broken Access Control), the winner flips by application domain:

Domain Claude 4 Sonnet Gemini 2.5 Pro
Data science 0.0% 16.7%
DevTools 33.3% 0.0%
AI 0.0% 50.0%
DevOps 0.0% 0.0%

Same CWE, same benchmark, opposite winners depending on what the application is for. If you take one table from this post, take this one: the “safest model” depends on the domain, which means there is no safest model.

The v3 revision adds the finding that best explains why the floor is where it is. Split the tasks by how many files the fix touches. Claude 4 Sonnet’s functional pass rate goes 66.9% on single-file tasks, 39.1% on two-file, 30.3% on three or more. Its security pass rate goes 15.4%, 4.3%, 3.0%. Security degrades faster than functionality, and it degrades along the axis of cross-file reasoning. The same trend holds for Gemini 3 Pro, Gemini 2.5 Pro and Kimi K2. This is Veracode’s CWE-80/CWE-117 floor showing up again at the repository level: the moment a security property has to hold across a module boundary, every model loses it.

Datadog Security Labs and Tenzai supply the correlated-failure evidence. Datadog gave one specification to three models (Sonnet 5, Composer 2.5, GPT 5.5), each in default mode and plan mode. Six implementations of a document portal: login, roles, password reset, file upload, search, comments.

All six shipped the same IDOR. Any authenticated user could read, download, or comment on any document, regardless of ownership. Datadog went back and checked whether the prompt was ambiguous. It was not, exactly. It was incomplete:

“The prompt did not specify that the user should only be able to access files that they own. This finding provides a significant signal: A high-level plan cannot compensate for the absence of explicit security constraints.”

That is the core defect. “Users can upload documents” does not state “users can only see their own documents.” Ownership is a product decision, not a coding decision, and no model can invent a decision you never made. Across three vendors and two operating modes, none of them asked.

Plan mode, notably, did not help: “no meaningful correlation between plan mode and more secure code.” Composer 2.5’s plan-mode output was strictly worse than its default-mode output: the JWT secret fell back to a hardcoded dev-secret-change-me with no startup check, leaving any deployment missing that environment variable open to full authentication forgery.

Tenzai built 15 applications with five agents (Cursor, Claude Code, Codex, Replit, Devin) and included a link-preview feature that fetches a user-supplied URL, with no security guidance. All five agents shipped an SSRF. Meanwhile, across all 15 applications, they found zero exploitable SQL injection and zero exploitable XSS. Their framing is the cleanest available: agents handle vulnerability classes with clear do/don’t rules and built-in framework protection; they fail where “the line between safe and dangerous depends heavily on context.” Login rate limiting was missing in every app but one, and that one was bypassable via X-Forwarded-For.

Best single configCodex + GPT-5.417.3%All thirteen pooledany config solves it33%What you needevery security task100%
Share of SusVibes security tasks solved. Endor Labs, Agent Security League, 15 April 2026 (updated 7 May). Thirteen agent-and-model configurations over 179 tasks and 72 weakness classes. The third bar is not a measurement, it is the target.

What actually ships

The deployed-app data is worse than the benchmark data, and the paper is direct about why. These apps are not built by accumulating small reviewed changes; they are “produced through intense bursts of project-level iteration,” which means “few human reviews and hardening are likely to be applied before deployment.”

arXiv:2606.23130 fingerprinted 10,517 real vibe-coded repositories (AI authored the first commit; more than 85% of commits and lines are AI-authored; 94.5% are web applications; 11.7% are publicly deployed), then audited a random 200 of the deployed ones with a hybrid agent-and-human workflow, yielding 1,471 validated vulnerabilities. 90% of the applications had at least one. 20% of the findings were Critical, 56.7% High, 2.2% Low.

The distribution, against OWASP’s own incidence baseline for human-led development. That last column is OWASP’s reported application-level incidence rate, and the authors use the OWASP Top 10 (2025) as the human-led proxy specifically because its underlying statistics were collected before AI coding tools were widespread:

OWASP 2025 category Share of findings Apps affected OWASP baseline
A01 Broken Access Control 36.0% 75.5% 3.74%
A04 Cryptographic Failures 20.7% 63.0% 3.80%
A05 Injection 17.7% 61.5% 3.08%
A07 Authentication Failures 9.0% 42.5% 2.92%
A06 Insecure Design 8.6% 43.5% 1.86%
A02 Security Misconfiguration 4.9% 27.0% 3.00%

Broken Access Control moved from 4th place in human-written software to 1st, at up to 20× the baseline incidence. 82.8% of those access-control failures sit in backend code. The cryptographic failures concentrate in configuration (42.8%), and injection skews frontend (59.4%). Different layers of the stack, same direction.

Commercial scans agree. Vibe App Scanner: of 359 Supabase-backed applications, 39.3% had a Row Level Security or data-exposure problem allowing unauthorized reads; 5.4% of all apps shipped a secret in client code. Escape: 2,038 highly critical vulnerabilities and 400+ leaked secrets across 1.4K applications, including 175 instances of exposed PII. CVE-2025-48757, in which Lovable generated Supabase tables without RLS, reached CVSS 9.3 across 170+ applications.

The paper’s root-cause taxonomy explains why iteration makes this worse, and it is worth reading directly. The largest class (49.9%) is knowledge defects: security requirements that were never stated, like hashing credentials or validating input at a sensitive sink. Then objective defects (30.6%): security subordinated to making the demo work, including hardcoded bypass routes added to fix an authentication error during debugging. Then memory defects (19.5%): an authorization middleware applied to one new router and not the eleven existing ones, or a TODO in the sign-in route that shipped anyway at 89.2% Critical-or-High severity.

The detail I keep coming back to: in 32% of the runs where the agent reintroduced a known vulnerability, it had identified the risk and shipped the insecure code anyway, usually by moving the warning into a comment.

Where the studies contradict each other

Every study here was run differently, and on the two occasions I found the same model ranked near-best and near-worst, the explanation was methodology rather than error. Worth showing rather than averaging away.

Gemini 2.5 Pro is three different models depending on who you ask. AppSecSanta: mid-pack, 23.0%. Armis: 13th of 18, near-worst, 67.74% vulnerable scenarios. SusVibes: the best model on the security-normalized metric (30.4%), while being the worst on functional correctness (18.3% on SWE-agent). All three can be true: SusVibes conditions on solved tasks, Armis counts scenario-level failures, AppSecSanta counts confirmed SAST findings in snippets. But you cannot cite one of these without the other two if you want to be honest.

Grok 4’s favorable signature is single-source. Tightest language split (1.8 points), lowest injection count, minimal debug defaults, but it appears only in AppSecSanta’s Feb 2026 snapshot. No other benchmark tested it. Treat it as unreplicated.

Vendor benchmarks and CVE attribution do not measure the same thing. Everything above counts vulnerabilities in code that was generated for a test. Georgia Tech’s Systems Software & Security Lab runs the other experiment: the Vibe Security Radar scans public advisory databases for AI-tool signatures and counts what actually reached a CVE. 74 confirmed cases at time of writing, 14 Critical and 25 High, with command injection, authentication bypass and SSRF leading, the same categories the benchmarks flag. The trend line is the part worth watching: roughly 18 cases across the back half of 2025, then 56 in the first quarter of 2026, 35 of them in March. Small absolute numbers with a steep slope, and a large dark figure, since attribution requires a tool signature to survive into the public record.

Every model × CWE table is stale within a quarter. The AppSecSanta table above was collected in Feb 2026 against GPT-5.2, Claude Opus 4.6, and Gemini 2.5 Pro. The frontier as of this writing is GPT-5.5, Claude Opus 4.7, and Gemini 3.1 Pro. Armis measured the generational swings directly (Gemini −29 points, Claude Sonnet −11 within one generation). Any vendor ranking you read today describes a version that is already being replaced.

So what does the third model buy you?

You can price this against the data. Take the standard test case, Datadog’s document-portal spec (a notes app with login, file upload, URL preview, search, and comments), and map each feature to what the studies say about it:

Feature CWE family What 3 models buy Evidence
URL preview CWE-918, SSRF Nothing 5 of 5 agents failed it in Tenzai; highest single CWE in AppSecSanta (32 findings), evenly spread
Get document by id CWE-639/862, IDOR Nothing 6 of 6 implementations in Datadog, across models and modes
File upload CWE-22/23, CWE-434, CWE-770 Partially Traversal is a named universal blind spot (Armis); type/size validation is idiosyncratic: only one of Datadog’s six relied purely on client-supplied MIME types
Login CWE-287, CWE-347, CWE-613 The most A07 spread of 1-to-5 across models in AppSecSanta; token revocation, CSRF coverage, and password-version claims differed per implementation in Datadog
Comments CWE-79/80, XSS Conditionally Industry floor is a 15% pass rate (Veracode), but Tenzai found zero exploitable XSS because frameworks auto-escape; Datadog’s 25 innerHTML findings concentrated in one of six builds
Secrets and env defaults CWE-798 Little arXiv: keys falling back to known defaults triggered in 11 of 24 replay runs; Datadog’s one hardcoded-JWT case was the plan-mode build

Six features. The ensemble moves two materially, one partially, and three not at all. The three it does not move are precisely the ones carrying Critical severity in the deployed-app data.

Somebody finally measured the pooling

Earlier versions of this argument had to reason from per-model failure rates, because the pooling experiment had not been run end to end. One leaderboard and three papers now have, and they agree on the shape.

The union of thirteen configurations still leaves two thirds on the table. Endor Labs runs SusVibes as a live leaderboard, the Agent Security League: thirteen agent-and-model combinations (Cursor, Claude Code, Codex, SWE-agent, over Claude Opus/Sonnet, GPT-5.x and Gemini 3.x) across 179 feasible tasks and 72 weakness classes, with prompt hardening, workspace sanitization and post-hoc cheating detection so agents cannot recover the fix from git history. Best functional score: 84.4% (Cursor + Claude Opus 4.6). Best security score: 17.3% (Codex + GPT-5.4). Median gap between working and secure: 45 points. Then Endor pools the configurations, and reports that even across all thirteen, only 33% of the security tasks are solved. Thirteen agents, and two out of three tasks are solved by none of them. Three models is a much thinner sample than thirteen.

Pipelines beat panels, and the lift comes from the scanner. CSIRO’s Multi-LLMSecCodeEval (arXiv:2603.22717, March 2026) built ten coordination strategies over two datasets: parallel generation, cross-model verification, majority voting, chain-of-debate, and hybrids with CodeQL in the loop. The best hybrid reached 97–99% secure output against 39–73% insecure for the same models running alone. Read the ablation before celebrating. The lift came from static analysis sitting inside the pipeline; LLM-only collaboration moved far less. CWE-22, CWE-215, CWE-732 and CWE-190 survived every configuration. The authors land on the same conclusion this post arrives at from the other direction: “secure code doesn’t emerge from scale; it arises from carefully orchestrated multi-model system design.” One caveat on the roster. Mistral-7B, CodeLlama-7B, GPT-3.5 and GPT-4o are a generation or two behind anything you would ship today, so take the shape and not the absolute numbers.

Consensus is the wrong selection rule. Vallecillos-Ruiz et al. tested agreement against diversity in code-generation and repair ensembles, and named the failure mode: consensus selection falls into a popularity trap, upweighting outputs that are common precisely because every model learned them from the same corpus. Diversity-based selection captured up to 95% of the theoretical ensemble ceiling; voting did not come close. Almeida et al. (arXiv:2607.03174, July 2026) tested the same premise as software fault tolerance, 1-out-of-2 redundancy over LLM-generated and human-written implementations, and found the reliability gain real but bounded by exactly how much the failures overlap.

That is the whole argument in one line: ship the diff, do not ship the agreement. Where three models disagree you have found something. Where they agree you have found the training distribution.

The supporting anchor from AppSecSanta points the same way. 59.5% of confirmed vulnerabilities were flagged by only one of five SAST tools (26.1% by two, 14.4% by three or more). Five detectors looking at the same code agreed far less than the pooling logic needs them to, which is the argument for running the union, and the argument against reading the intersection as a clean bill of health.

The deeper problem with the intersection logic: three models agreeing is not independent evidence. They share training corpora, share the same insecure idioms from public code, and share the same inability to infer authorization requirements that were never written down. They are three samples from one distribution, not three witnesses. Vallecillos-Ruiz et al. named the consequence when they tested selection rules directly: agreement gets upweighted precisely because it is common, which is the popularity trap.

What actually moves the needle

The most useful experiment is the mitigation replay in arXiv:2606.23130. The authors took 15 real vulnerabilities from deployed vibe-coded applications and replayed them 360 times across eight configurations, varying one factor at a time. The baseline configuration (Claude Code, mid-tier model, casual prompt) reintroduced the original vulnerability in 40% of runs.

Change Trigger rate Delta
Baseline 40% ref
Weaker model (Haiku 4.5) 40% ±0
Stronger model (Opus 4.7) 33% −7
Hardened harness (security skill) 22% −18
Prompt: “review your changes” 18% −22
Prompt: “polished code” 33% −7
Prompt: “ready for production” 13% −27
Prompt: detailed professional spec 56% +16

Three things follow.

Model capability is the weakest lever tested. A tier down changed nothing. A tier up bought 7 points. “Production-ready” bought 27. A detailed, professional specification made things 16 points worse, because the agent followed the spec more literally and stopped exercising its own judgment. The effect differs by root cause, which matters for workflow design: knowledge defects respond to a stronger model (trigger rate 60.0% → 13.3% when switching Sonnet to Opus), while objective defects got worse with the stronger model (+27%): more capability, same instinct to make the demo work.

Even the best lever does not close it. At the 13% floor, 6 of 15 vulnerabilities still triggered in at least a third of runs, and no configuration eliminated all of them. The most persistent, storing an OAuth token in plaintext, triggered in 17 of 24 runs. The strongest model triggered it in all three of its runs.

Security hints help at the margins and cost you functionality. SusVibes tested telling the model which weakness to avoid. Handing it the correct answer moved correct-and-secure patches from 11.8% to 15.1%, while dropping functional correctness. Asking the model to identify the risk itself cost 7 points of functionality for 2.7 points of security. The models also selected 7.2 CWE types per task against an average of 1.1 ground-truth types, with a maximum recall of 0.667. They cannot reliably identify the risk even when asked to.

What I’d actually do

Generate with three models. It costs almost nothing: AppSecSanta’s entire 522-sample study ran on under $10 of API credits. It will catch the quirks that belong to one model and not the others: this one’s eval(), that one’s debug flag, the third one’s stale dependency. Then run the checks below, because none of them are automatable and every one of them sits in the correlated-failure set.

  1. Write the authorization sentence into the spec. One line per resource: “A user can only read, download, and comment on documents they own. Admins can read all.” The models cannot derive this and will not ask.
  2. Test for IDOR with two accounts. Log in as user A, request an object belonging to user B, and expect a 403. Enumerate every GET, PATCH, and DELETE /resource/:id route and walk the list.
  3. Allowlist the fetcher. If the app fetches user-supplied URLs: allowlist scheme and host, resolve DNS yourself, re-check after redirects, block RFC1918 and link-local ranges.
  4. Escape at the sink. Audit every innerHTML, dangerouslySetInnerHTML, document.write, and v-html. The framework saves you until someone reaches for one of these.
  5. Make secrets hard-fail at startup. A missing or placeholder environment variable should crash the process, not fall back to dev-secret-change-me. Grep the client bundle for sk_, service_role, and PEM blocks.
  6. Make tokens die. On password change, logout, and role change. Four of Datadog’s six implementations lacked revocation.
  7. Rate-limit every authentication endpoint, and verify the limit keys on something the attacker does not control. The one rate limiter Tenzai found was bypassable via X-Forwarded-For.
  8. On Supabase, enable Row Level Security on every table, then query each one with the anon key and see what comes back. This is the highest-value five minutes available.
  9. Re-run all of it after every agent iteration. The paper singles out incomplete change propagation as “especially common in Broken Access Control and Injection, where the same protection often needs to be applied consistently across multiple endpoints, handlers, or sinks”. The agent applies your fix in one place and not the other eleven.
  10. Add “production-ready” to the prompt. Two words, −27 points of vulnerability reintroduction. The cheapest control on this list, and nowhere near sufficient on its own.

The shape of the pipeline that follows from all of this: a spec with the authorization rules written down, then models A/B/C, then a union scan (SAST and DAST over all three outputs), then an ensemble layer that catches the style bugs, then a human gate for the architecture bugs: who owns this row, which hosts may be fetched, what happens when the environment variable is unset. The boundary between the last two is one question: can this be derived from the code alone?

The part that stays yours

Multi-model generation is diversity, and diversity is worth having. It catches one model’s eval(), another’s debug flag, another’s stale dependency. It is nearly free, so run it. Just read the disagreements rather than the agreements, because consensus selection buys you the popularity trap.

It will not close the gap, though. Thirteen frontier configurations pooled together solve a third of the security tasks in SusVibes. Three will do worse than that.

And it makes no security decisions at all. Ownership, trust boundaries, allowlist semantics, and secret lifecycle come from requirements the spec never stated, and correlated models fail them correlatively. A better model does not fix it (±0 to −7 points, and worse on objective defects). Plan mode does not fix it (no measurable effect). A security prompt barely dents it (+3.3 points, paid for in functionality).

Models write complete code for an incomplete spec, and it compiles, and the tests pass, and it looks finished. That’s the whole failure mode. Every control in this post either catches the spec gap or it doesn’t, and the ones that catch it are the ones a person has to run.

So pick your models on cost and speed. Then go write the authorization sentence down.


Sources

  • AppSecSanta · AI-Generated Code Security Study 2026 · 6 models × 87 prompts, 522 samples, 5 SAST tools, every finding hand-validated. Data collected Feb 2026, re-audited May 2026.
  • Datadog Security Labs · Putting models to the secure coding test: plan vs default mode · Aug 2026. Code and findings: github.com/DataDog/putting-models-to-the-secure-coding-test
  • SusVibes, arXiv:2512.03262v3 · Is vibe coding safe? · ICML 2026, revised Aug 2026. 186 tasks, 79 CWE types, 12 agentic settings.
  • arXiv:2606.23130 · Understanding the (in)security of vibe-coded applications · Jun 2026. 10,517 repositories, 200 deployed applications audited, 1,471 vulnerabilities, 360-run mitigation replay.
  • Armis Labs · Trusted Vibing Benchmark · 18 models × 31 scenarios, updated monthly. March 2026 snapshot cited.
  • Veracode, 2026 GenAI Code Security Report · 28 July 2026. 100+ models over four years, 11 new in the Summer 2026 dataset, 80 tasks, 4 languages. Announcement: AI is writing more of your code but security hasn’t caught up. The earlier Spring 2026 update (24 March 2026) carries the per-language breakdown and the OpenAI-specific 70–72% reasoning figure that is widely misquoted as a cross-vendor average.
  • Tenzai · Bad Vibes: comparing the secure coding capabilities of popular coding agents · Jan 2026, agents tested Dec 2025. 5 agents, 15 apps, 69 vulnerabilities, 6 Critical (Claude Code 4, Devin 1, Codex 1). Independent write-up: CSO Online, 14 Jan 2026.
  • Vibe App Scanner · We scanned 1,215 vibe-coded apps · Dec 2025–Aug 2026. Self-selected sample; figures are floors, not ceilings.
  • Escape · The state of security of vibe coded apps · 1.4K applications scanned.
  • CVE-2025-48757 · Lovable + Supabase RLS, CVSS 9.3.

Where the multi-model workflow is actually recommended:

  • Addy Osmani · My LLM coding workflow going into 2026 · 4 Jan 2026. Recommends trying models in parallel to cross-check approach; framed as quality, not security.
  • The Comparison Pattern · A practical pattern for comparing AI-generated code before it reaches production · Mar 2026. Three models side by side; the advice is to read the divergence, not the agreement.
  • Cursor community forum · Nov 2025. Users asking for tooling to run one task across several models and have them review each other.
  • EnsLLM, arXiv:2503.15838 · Mahmud, Duan, Pasareanu, Yang · Mar 2025, revised Jul 2025. Similarity-based selection with a voting step over multiple LLMs. HumanEval 90.2% against GPT-4o’s 83.5%, a correctness result rather than a security one.

On the multi-model question specifically:

Real-world attribution and industry telemetry:

Methodology note: this post cites generation-benchmarks only (does the model emit vulnerable code?). Detection benchmarks (can a scanner find the bug?) are a different measurement and are excluded throughout. Where studies disagree, as on Gemini 2.5 Pro (best-in-class on SusVibes’ security-normalized metric, near-worst on Armis, mid-pack on AppSecSanta), we report the disagreement rather than averaging it. Full model × CWE tables, confounder analysis, and the experiment design that would settle the open questions are in the accompanying research memo.