Coding agents have gotten good at the bugs security tooling was built to find. They bind SQL parameters. They escape template output. Then they ship an endpoint that returns any invoice whose id you put in the URL, because nobody told them invoices belong to someone.

That is the shape of AI-generated code security in 2026. The pattern-matchable flaws are thinning out. The flaws that need to know who owns what are not, and they are the ones a diff reviewer and a scanner both walk past.

An agent can only enforce the rules it was given. "Users see their own records" is a rule most prompts never state.

What the studies say about AI-generated code

The baseline is not encouraging. Veracode's 2025 GenAI Code Security Report tested more than 100 models and found 45% of samples failed security tests. A year later its 2026 report found the pass rate stalled at about 56%. Code that compiles nearly every time still fails a security check close to half the time. Coding-specialized models did no better than general ones.

Notice what that benchmark measures: injection, cross-site scripting, weak crypto. It does not test authorization, because authorization depends on a data model the benchmark cannot see. The studies that do look at real apps tell a sharper story.

Tenzai had five coding agents build the same three applications. SecurityWeek reported 69 vulnerabilities across the 15 apps, and no exploitable SQL injection or XSS. Improper API authorization was among the most common problems. Agents handled simple ownership rules and broke down as the rules got more involved. Four of five accepted negative order quantities.

Apiiro's analysis of large enterprise repositories, covered by The Register, found AI-assisted code had 76% fewer syntax errors and 322% more privilege-escalation paths than code written without it. Fewer typos, more ways to become someone else. That is exactly the trade a line-by-line reviewer is worst at noticing.

On the backend specifically, the BaxBench benchmark from ETH Zurich asked models to build 392 backend services. Even the best model got most tasks functionally correct only about 62% of the time, and roughly half of the correct programs could be exploited.

Broken access control is still the top web risk

None of this is new risk. OWASP Top 10:2025 keeps Broken Access Control at number one, now mapped to 40 weaknesses and more than 1.8 million recorded occurrences in the dataset. In APIs it has its own name. Broken object-level authorization is API1:2023, rated easy to exploit and widespread.

The mechanics are simple. The server trusts an object id the client sent and never asks whether the caller owns that object. OWASP's IDOR prevention cheat sheet is clear that random UUIDs do not fix this. They make ids harder to guess. They do not make the check exist.

WHAT THE AGENT WROTE
  GET /api/v1/invoices/:id
  invoice = db.invoices.find(id)
  return invoice                      <- anyone's invoice

WHAT IT NEEDED
  GET /api/v1/invoices/:id
  invoice = db.invoices.find({
    id,
    org_id: session.org_id           <- from the session,
  })                                     never the request
  if (!invoice) return 404
  return invoice

Same route. Same tests pass. One line decides
whether you have a tenant boundary.

Why code review misses it

A reviewer reads the diff. The diff shows a handler that loads a record and returns it, cleanly written, with a test that passes. Nothing on the screen is wrong. What is wrong is absent, and spotting an absence needs the whole data model in your head: who owns invoices, which roles can see them, whether this route sits behind the middleware that sets the org.

The Stanford study "Do Users Write More Insecure Code with AI Assistants?" adds the human factor. Participants with an AI assistant wrote less secure code than those without, and were more likely to believe their code was secure. Polished output earns trust it has not earned.

Duplication finishes the job. GitClear's analysis of 211 million changed lines found copy-pasted code overtaking refactored code for the first time in 2024. A missing check in one generated helper becomes the template for the next ten routes. Fix one, and nine copies stay open.

Scanners do not close the gap either. A missing ownership check has no tainted input and no malicious payload. The response is a healthy 200 with valid JSON. Only a test that knows the response belongs to a different account can tell it is a breach.

What it looks like in production

Optus is the long-tail version. Australia's regulator alleged that a coding error broke an API's access controls in 2018, after review and testing. Optus fixed it on its main domain in 2021 but not on a dormant sibling domain. In 2022 an attacker used that endpoint to pull records on about 9.5 million people. A fix in one place, a copy left open.

The vibe-coded version is faster. A researcher's scan behind CVE-2025-48757 found 170 of 1,645 showcased Lovable apps with Supabase row-level security missing or wrong, letting anyone read or write tables. The built-in checker only confirmed a policy existed, not that it was correct. In February 2026, Wiz found Moltbook, an AI-agent social network whose founder said no code was hand-written, exposing its production database through a client-side key and no row-level policies: about 1.5 million agent API tokens and thousands of private messages.

Escape passively scanned more than 5,600 public vibe-coded apps and found over 2,000 vulnerabilities and 400 exposed secrets, most of them reachable without logging in.

"A policy exists" and "the policy is correct" are different claims. So are "there is auth middleware" and "this route checks ownership."

How to catch it before release

Write the rule down first. If the requirement "a user only sees their own organization's invoices" never appears in a spec, a prompt, or a test, the agent has nothing to satisfy and the reviewer has nothing to check against. Then put it in the code path once: a central scoping helper that every query uses, with identity taken from the session.

OWASP's own advice is to put functional access-control checks in unit and integration tests. Corey Ball's Hacking APIs describes the attacker's version, and it makes a good test: create two accounts, capture A's requests, replay them with B's token and B's ids. Do the same with a low-privilege token against admin routes. It needs two identities and knowledge of the data model, which is why it belongs in a pentest and not in a diff review.

BEFORE AN AGENT-HEAVY RELEASE SHIPS

[1] Two-account replay
    Every route that takes an id, called as the
    wrong tenant, returns 404 or 403. Never 200.

[2] Role replay
    Admin and internal routes refuse a normal token.

[3] One scoping path
    Queries filter by the session's org in a shared
    helper, not hand-written per route.

[4] Database policies tested, not just present
    Row-level security denies a cross-tenant read
    with the public client key.

[5] Copies found
    When a check was missing in one handler,
    every similar handler was checked too.

[6] Business rules hold
    Negative quantities, skipped workflow steps,
    and reused one-time tokens are rejected.

Let the agent write it. Test what it wrote.

AI-generated code is not going away, and it should not. It is good at the parts security tools were built to check. The part left over is the part that needs context: who owns what, and whether every one of today's new routes knows it.

GhostProbe tests that part. The Pentest job is $1,490 for up to four staging or preproduction addresses you own. Connect up to 2 GitHub repositories and the review reads the handlers as well as hitting the running app, which is how missing ownership checks and their copies get found. Recon is $490 for one address. A security engineer reproduces each finding, removes false positives, writes the fix, and signs the dossier.

Run it on the build your agent produced this week, while the code in the report is still the code in production.

Buy Pentest Buy Recon