Ship AI code without shipping holes.

What the research actually says, six weaknesses to hunt first, and the checks that catch them without slowing you down.

A padlock resting on a laptop keyboard
Photo by FlyD on Unsplashdithered by Cyborb

AI-generated code is only as secure as the checks you run on it. In Veracode’s tests of more than 150 models, 45% of coding tasks produced code with a known security flaw, even though almost all of it compiled. The answer is not to stop using AI. It is to know the few weaknesses it gets wrong most, check for them on every change, and let scanners do the repetitive part.

This guide covers what research says about AI-generated code security, six weaknesses to hunt, the free tools that catch them, and prompts that help. For the review process itself, see our guide to reviewing AI-written code by risk.

The short version
  • In large tests, about half of AI coding tasks still produce a known security flaw. The best reasoning models do better, but not well enough to skip checks.
  • Hunt six weaknesses first: injection, broken access control, hardcoded secrets, risky dependencies, path traversal and careless error handling.
  • People who code with AI tend to trust the result more than they should, so build checks that do not depend on trust.
  • Run a static scanner, a dependency audit and a secret scanner on every change, ideally in CI.
  • Asking for secure code helps, especially with reasoning models. It does not replace the checks.

How secure is AI-generated code?

Separate tests point the same way: AI code usually works, and it is often not safe.

45%
of coding tasks produced code with a known flaw, across 150+ models
Veracode, March 2026
15%
security pass rate on cross-site scripting tasks
Veracode, March 2026
1 in 2
working backend programs could be broken by expert-written exploits, on average
BaxBench, 2025

The details matter. Veracode found that models now handle SQL injection well, with an 82% pass rate, but pass only 15% of cross-site scripting tasks and 13% of log injection tasks. Java was the weakest language, at 29%. OpenAI’s GPT-5 models with extended reasoning reached 70 to 72%, against about 55% for other recent releases. That is progress, not a free pass.

BaxBench, a 2025 research benchmark of 392 backend tasks, asked models to build working servers and then attacked them. Even the best model at the time produced correct code only 62% of the time, and around half of the correct programs could be exploited.

The human side matters too. In a Stanford study published at CCS 2023, people with an AI assistant wrote significantly less secure code than people without one, and were more likely to believe their code was secure. The model in that study is several generations old. The overconfidence is the part to design around.

Six weaknesses to hunt first

Each maps to a category in the OWASP Top 10:2025, the standard list of web application risks. And each is easy for an AI to get wrong for the same reason: the insecure version also works, so your tests pass.

WeaknessThe typical mistakeWhat to check
InjectionBuilds SQL, shell commands or HTML by pasting in user inputParameterized queries, no shell calls with user input, escaped HTML
Broken access controlChecks permissions in the interface but not on the serverEvery endpoint checks who is asking and whether they own the record
Hardcoded secretsInlines a key so the demo runsNo keys in code, logs or front-end bundles
Risky dependenciesAdds a package that is outdated, unmaintained or does not existEvery new package is real, needed and maintained
Path traversalJoins a user-supplied file name onto a folder pathResolve the path and confirm it stays inside the folder
Careless error handlingReturns stack traces to users, or logs raw user inputGeneric errors for users, sanitized logs for you

Injection

For SQL, the fix is old and reliable: pass user input as a parameter, never as part of the query string.

TypeScript
// Risky: the input becomes part of the SQL itself
await db.query(`SELECT * FROM users WHERE email = '${email}'`);

// Safe: the driver sends the input separately from the query
await db.query("SELECT * FROM users WHERE email = $1", [email]);

Cross-site scripting is where models struggle, with that 15% pass rate. Search every diff for innerHTML, React’s dangerouslySetInnerHTML and any template helper that skips escaping. For shell commands, the safest input is none: call the program with fixed arguments instead of building a command string.

Broken access control

It is number one on the OWASP list, and AI-built apps show why. In 2025, researchers scanned 1,645 apps built with Lovable and found 170 of them (10.3%) with database rules that let strangers read or change data, including names, phone numbers and payment details. The apps worked perfectly for their owners.

The lesson is not about one product. If your front end talks to a database directly, the rules inside the database are your only lock. Test it the way an attacker would: sign in as one user, then request another user’s record by changing the ID. Our guide to adding login to your app covers picking an authentication provider that gets these checks right by default.

Secrets and dependencies

Hardcoded keys get their own guide: how to keep API keys safe. Dependencies carry a newer risk. In a study of 576,000 code samples from 16 models, 19.7% of recommended packages did not exist, and attackers can register those names. That attack is called slopsquatting.

Path traversal

When code builds a file path from user input, a name like ../../.env walks out of the folder you meant. Resolve the path, then refuse anything outside the base folder.

TypeScript
import path from "node:path";

const base = path.resolve(UPLOAD_DIR);
const target = path.resolve(base, fileName);

// Refuse anything that escapes the upload folder, such as "../../.env"
if (!target.startsWith(base + path.sep)) {
  throw new Error("Invalid file name");
}

Better still, store uploads under generated IDs, so a user’s input never becomes a path at all.

Tools that catch problems automatically

People miss the one unescaped variable in a long diff. Scanners do not get tired, and these four are free to start with.

01SemgrepStatic analysis

A pattern-based scanner for many languages. semgrep scan runs on your machine without an account.

02GitHub code scanningStatic analysis

Runs CodeQL, GitHub’s analysis engine, or a third-party tool on your repository. Free for public repositories; private ones need a GitHub Code Security license.

03OSV-ScannerDependencies

Google’s open-source scanner checks your lockfiles against the OSV database of known vulnerabilities.

04GitleaksSecrets

Finds keys and tokens in files and git history, and can run before every commit.

A local run looks like this:

Terminal
# Static analysis, no account needed
semgrep scan

# Known vulnerabilities in your dependencies
osv-scanner scan source -r .

# Secrets anywhere in your git history
gitleaks git -v .

Then move them into CI, so they run on every change instead of when you remember. Treat a new finding like a failing test: fix it, or write down why it is a false positive. For the AI reviewers that read a whole pull request instead of matching a fixed pattern, our comparison of AI code review tools covers what each one catches.

A checklist for every AI-written change

Security check for AI-written code0 of 8

Prompts that ask for secure code

Asking helps, with a catch. In BaxBench, a generic reminder to write secure code gave reasoning models a considerable boost, while other models barely improved. Naming the exact weaknesses improved security the most, but models then produced fewer working programs. So ask, and keep the checks.

Put standing rules in your agent’s project instructions:

PromptSecurity rules for your agent
When you write or change code in this project:
1. Use parameterized queries. Never build SQL, shell commands or HTML from user input.
2. Enforce authorization on the server for every endpoint: check who the user is and that they own the record.
3. Never hardcode secrets. Read them from environment variables.
4. Do not add a dependency without asking me first. Tell me its name, what it does and why existing code cannot do the job.
5. Validate the name, size and type of anything a user uploads.
6. Show users generic error messages. Never log passwords, tokens or full request bodies.

After each change, ask for a focused review:

PromptSecurity self-review
Review the change you just made the way a security engineer would. For each finding, give the file and line, the attack, a concrete malicious input and the fix.
Check specifically for: injection (SQL, shell, HTML), missing authorization checks, secrets in code or logs, new dependencies, path traversal, and error messages that leak internals.
If you find nothing, say which of these you checked and how.

A model reviewing its own work shares its blind spots. Treat its findings as leads, and let the scanners have the final word on what they cover.

FAQ

Is AI-generated code less secure than code written by people?

It is not a clean comparison, because people write insecure code too. The research shows that models alone produce known flaws in a large share of tasks, and that people using an assistant tend to overrate the result. Review and automated scanning are how you close the gap.

Which AI model writes the most secure code?

Rankings change with each release, so check current results instead of trusting an old list. In Veracode’s March 2026 update, OpenAI’s GPT-5 models with extended reasoning passed 70 to 72% of security tasks, against about 55% for other recent releases. None was safe enough to skip review.

Can an AI review its own code for security?

It helps as a second pass, especially with a specific checklist like the prompt above. But a model reviewing its own work shares its blind spots, so treat its findings as leads and keep the scanners running.

Do I need paid security tools?

Not to start. Semgrep’s open-source engine, OSV-Scanner and Gitleaks are free, and GitHub code scanning is free on public repositories. Paid tools add coverage, triage and support, which matters more as a team grows.

Key takeaways
  • About half of AI coding tasks still produce a known flaw in large tests, and insecure code usually passes functional tests.
  • Hunt injection, broken access control, secrets, dependencies, path traversal and error handling first.
  • Scanners in CI do the repetitive reading, so your attention goes to the risky parts.
  • Ask for secure code, then verify it anyway.

Read next: how tests keep an agent honest, and why prompt injection is the risk agents add.

Sources
  1. Spring 2026 GenAI code security update, Veracode, March 2026
  2. BaxBench: can LLMs generate correct and secure backends?, Vero et al., arXiv, February 2025
  3. Do users write more insecure code with AI assistants?, Perry et al., CCS 2023
  4. Statement on CVE-2025-48757, Matt Palmer, May 2025
  5. OWASP Top 10:2025, OWASP
  6. We have a package for you: package hallucinations by code generating LLMs, Spracklen et al., USENIX Security 2025
  7. About code scanning, GitHub Docs
  8. Semgrep CLI, Semgrep Docs
  9. Scanning project source, OSV-Scanner
  10. Gitleaks, Gitleaks on GitHub
cyborb.ai

Stop reading about it. Build it.

Describe what you want in plain words. Cyborb plans the work, writes and runs the code, makes the assets, and puts the result online.

Download Cyborb

Free to start. No card required.