Is AI-Generated Code Secure? Risks and How to Gate It

AI coding assistants now write or influence a large share of the code shipping to production. They are fast, tireless, and genuinely useful. They are also confidently wrong about security in ways that a junior engineer usually is not, because they will produce a plausible, well-formatted, insecure implementation and never flag their own uncertainty.

The uncomfortable headline that keeps circulating: roughly a quarter of AI-assisted code contains a security flaw. Treat that figure as directional rather than precise. The exact rate depends on the model, the language, and the prompt. The point stands regardless. A meaningful fraction of what these tools emit is exploitable, and none of it arrives labeled.

Why AI-generated code is often insecure #

Three structural reasons explain most of the risk.

Training data: Models learn from vast public code, and public code is full of insecure patterns. Tutorials use string concatenation for SQL because it reads cleanly. Stack Overflow answers skip authorization checks to stay on topic. The model absorbs the average of what it saw, and the average is not secure.

Missing context: The assistant does not know your threat model, your trust boundaries, or which function runs behind authentication. It cannot reason about whether a given input is attacker-controlled because it has never seen your architecture. It optimizes for code that looks correct in isolation.

Confident plausibility: The failure mode that matters most. AI produces security-relevant code (crypto, token handling, access control) with the same fluent confidence it uses for a loop. Plausible-but-wrong security code is worse than obviously broken code, because it survives a casual glance and reaches review looking finished.

The common flaw classes #

Across languages, the same categories show up again and again:

Injection: SQL, command, and template injection from string concatenation instead of parameterized queries.

Missing authorization: Endpoints that authenticate the user but never check whether that user may act on the requested resource.

Hardcoded and weak secrets: API keys inlined into source, default passwords, tokens with no rotation.

Insecure deserialization: Reaching for pickle, yaml.load, or native Java serialization on untrusted input.

Vulnerable dependencies: Suggesting an old package version with known CVEs, or a library abandoned years ago.

Weak crypto: MD5 or SHA-1 for passwords, ECB mode, hardcoded IVs, homegrown token schemes.

Missing input validation: Trusting request bodies, headers, and path parameters as-is.

Here is a representative AI-style snippet. It is idiomatic, it runs, and it is vulnerable to SQL injection.

python.python

# AI-generated: looks fine, is not
def get_user_orders(db, user_id):
query = "SELECT * FROM orders WHERE user_id = " + user_id
return db.execute(query).fetchall()

The fix parameterizes the query and does not trust the caller to have validated the input:

python.python

# Reviewed and hardened
def get_user_orders(db, user_id: int):
query = "SELECT * FROM orders WHERE user_id = ?"
return db.execute(query, (user_id,)).fetchall()

Same behavior, one is exploitable and one is not. The difference is exactly the kind of thing a reviewer or a scanner catches and an autocomplete does not.

The newer risk: package hallucination #

Supply chain is where AI introduces a genuinely new attack surface. Models sometimes invent dependencies. Asked for a library to do X, an assistant may confidently import a package that does not exist, because a name that fits the pattern is statistically likely even when it is not real.

Attackers noticed. They watch for commonly hallucinated names, register those packages on public registries, and wait for developers to paste AI output and run install. The malicious package then executes in your build. This is slopsquatting, a variant of typosquatting driven by model hallucination rather than fat-fingered typing. Any unfamiliar dependency an assistant suggests deserves a look at the real registry, the download counts, and the maintainer before it enters your lockfile.

How to gate it #

The goal is not to ban AI coding. It is to route AI output through controls that assume it is untrusted, because it is.

Mandatory human review: No AI-generated change merges without a human owner who understands it. Review is where missing authorization and business-logic flaws get caught, because scanners cannot see intent.

SAST and secret scanning in CI: Run static analysis and secret detection on every pull request and fail the build on high and critical findings. Do not leave these advisory.

SCA on every dependency: Software composition analysis flags vulnerable and hallucinated packages before they land. See dependency and SCA scanning for wiring this into the pipeline.

IaC scanning: AI writes plenty of Terraform and Kubernetes manifests, and it will happily open a security group to the world. Scan infrastructure as code with the same failing gates.

Guardrails and policy: Codify standards (parameterized queries, approved crypto, no inline secrets) as lint rules and policy-as-code so the machine enforces them, not tribal memory.

Treat AI output as untrusted input: The same posture you apply to a random contributor's first pull request. Verify, do not assume.

Grounding these gates in secure coding best practices keeps reviewers and rules aligned on the same standard.

Metrics that actually reflect the shift #

When AI writes a large slice of your code, "vulnerabilities found" stops being a useful north star. Volume goes up because output goes up. Shift the scoreboard toward leading indicators:

Guardrail coverage: What percentage of repositories and pipelines enforce SAST, SCA, secret scanning, and IaC gates.

AI-introduced flaws remediated: Of the issues traced to AI-generated changes, how many were caught pre-merge versus in production.

Time-to-remediate: How fast flagged findings actually close.

These measure whether your gates work, not whether your assistants make mistakes. They always will.

How to adopt AI coding safely #

A workable rollout looks like this:

Turn on the gates first. SAST, SCA, secret scanning, and IaC scanning failing on high and critical severity, before you scale up AI usage.

Set a clear rule: AI code is reviewed like any other code, and the human author owns it. "The model wrote it" is not a defense.

Verify every unfamiliar dependency against the real registry to shut down slopsquatting.

Encode your security standards as automated policy so correct patterns are the path of least resistance.

Track guardrail coverage and remediation, and feed real findings back into prompts and lint rules.

The call we'd make #

AI-generated code is not secure by default, and it is not going away. Both things are true. Ban it and you lose the velocity; trust it and you ship the flaws. The durable answer is to let the assistants write, and let a hardened pipeline decide what merges. Assume every AI-produced line is untrusted until a human and your scanners have signed off. Teams that build those gates get most of the speed and very little of the risk. Teams that skip them are shipping that quarter-of-all-flaws statistic straight to production.

For the broader program, start with our AI security guide and build the gates outward from there.