The volume problem is straightforward. AI assistants produce code faster than human reviewers can read it, and research tracking the resulting defect surge suggests the total defect count is rising even where per-line quality is comparable to human output.
The more useful observation is that AI-generated code fails differently, in patterns that are consistent enough to plan detection around.
How AI-generated code fails
It is plausible rather than correct. A model produces code that looks like the code it was trained on. In security-sensitive positions this is exactly the wrong property: a comparison that resembles a constant-time comparison, a token check that reads like a valid one, a permission check with the right shape and the wrong subject.
It reproduces training-data patterns, including outdated ones. Training corpora contain a great deal of code written before current best practice. Deprecated crypto choices, superseded framework idioms, and patterns that were fine in 2019 all appear fluently and confidently.
It handles the happy path. Error paths, edge cases, and failure modes are underrepresented in the code models learned from, and they are where security bugs concentrate — the unhandled exception that reveals a stack trace, the failure branch that returns success.
It invents dependencies. Package hallucination is well documented and creates a directly exploitable slot for an attacker to register the invented name.
Context is missing by construction. The model does not know that a function is only ever called with pre-validated input, or that a value comes from an untrusted source three layers up. It writes each function as if in isolation.
It is high-confidence and reads well. This is the property that most reduces reviewer scepticism. Human-written insecure code often looks rushed. AI-written insecure code looks like it was written carefully.
Where each technique lands
SAST is strongest against pattern-recognisable defects: injection sinks, unsafe deserialization, weak cryptographic primitives, hardcoded secrets, unsafe temp file creation. AI code produces plenty of these, and SAST catches them without needing the application to run — which matters when the volume is high.
Its blind spot is authorisation and business logic. A permission check that is present but checks the wrong subject is syntactically fine. SAST sees a check; it cannot know the check is wrong.
DAST tests the assembled, running system. It catches configuration and deployment issues, authentication handling, and the behaviour of the whole stack including gateways and proxies. It finds things that only exist once the pieces are connected.
Its blind spot is coverage: it can only test what it can reach and authenticate to, which — as we covered in why crawler-based DAST struggles in API estates — is often a small fraction of the real surface.
Reachability analysis does something neither of the others does: it tells you whether a vulnerable code path is actually invoked. Against AI-generated code this matters more than usual, because assistants generate a lot of code that is never called — helper functions written speculatively, alternative implementations left in place, error handlers for conditions that cannot occur.
Its blind spot is that it prioritises rather than detects. It makes a backlog tractable; it does not find anything SAST or DAST did not.
What none of them catch
Be honest about the gap, because it is the most dangerous part.
Wrong-but-valid authorisation logic. if (user.id == resource.owner_id) where the correct check involved the organisation, not the user. Every tool sees a correct-looking authorisation check.
Business logic errors. A discount that can go negative, a state machine with an unintended transition, a refund path that can run twice. These require knowing what the code was supposed to do.
Subtly wrong cryptography. Correct algorithm, correct library, wrong mode or wrong nonce handling. It passes every pattern check because every element is individually correct.
Missing controls. No tool alerts on the rate limit that was never written, or the audit log entry that does not exist. Absence is invisible to scanners.
These are precisely the failure modes AI-generated code is most prone to, because they are the ones where plausible and correct diverge. Which leads to the uncomfortable conclusion: the categories automated tooling handles worst are the ones AI code produces most.
A practical layering
- SAST in the IDE and on every PR. Fast, catches the pattern-recognisable majority, and gives feedback while context is fresh. Non-negotiable at high generation volume.
- Dependency and hallucination checks at commit. Verify every imported package exists, is the one intended, and is not newly registered. This closes the hallucination slot cheaply.
- Reachability to rank the resulting backlog. Otherwise volume makes the backlog meaningless.
- DAST against the deployed system, with coverage measured against a real endpoint inventory rather than a spec.
- Human review concentrated where tools are blind. Authorisation logic, state machines, cryptographic usage, money handling, and anything that deletes. This is where reviewer attention should be spent, and it is often spent instead on style issues a linter should own.
Point five is the one that requires an explicit decision. If AI generates most of your code, review capacity should shift decisively toward the categories automation cannot cover — which means consciously reviewing less of the code that SAST covers well.
How Safeguard helps
Reachability that makes an AI-scale backlog tractable. Safeguard determines whether vulnerable paths are genuinely invoked from your application, which is what converts thousands of findings into a ranked list a team can work through.
Dependency verification including hallucinated and newly registered packages. Safeguard's Supply Chain Core flags imports that do not resolve to established packages and packages registered suspiciously recently — the exact slot package hallucination creates.
Griffin for review at generation speed. Griffin performs security-focused review on pull requests, authors fixes, and tests them — matching review throughput to generation throughput rather than making human reviewers the bottleneck. It is aimed specifically at the reasoning-heavy categories, not at duplicating what a linter already does.
Continuous SBOM regardless of who wrote the code. Whether a dependency was added by a person or a model, it lands in the same CycloneDX and SPDX inventory with the same provenance and behavioural checks.
Prioritisation across techniques. Findings from static analysis, dynamic testing, and dependency scanning ranked together by reachability, exposure, KEV membership, and EPSS, so teams work one list instead of three.
Take your last twenty AI-assisted merges and check only the authorisation logic. That is the fastest way to find out whether this applies to you.
Sources: Cloud Security Alliance — AI-Generated Code Vulnerability Surge · Cloud Security Alliance — AI Coding Assistants as Attack Surface · Kusari — AI Coding Assistants in 2026 · OX Security — DAST Tools in 2026