Vet AI-Generated Code Before You Ship: A Security Checklist

··12 min read
Vet AI-Generated Code Before You Ship: A Security Checklist

Here's a number that should make every engineering lead uneasy: in a 2024 study of real-world code suggestions, researchers found that roughly 40% of AI-generated code samples in security-sensitive scenarios contained exploitable vulnerabilities. Not typos or style nits. Actual bugs an attacker could ride into your production environment. And yet the same tools that produce that code also make you feel productive enough to merge it without a second look.

That's the trap. AI coding assistants are genuinely good at boilerplate, glue code, and turning a vague prompt into something that compiles. What they're bad at is understanding your threat model, your data-sensitivity boundaries, and the fact that the "quick" SQL query they wrote concatenates user input straight into a database call. The model has no skin in the game. You do.

This article is a practical, no-fluff security checklist for vetting AI-generated code before it ships. We'll walk through a real before/after example, compare how the major assistants stack up on security, and give you a copy-paste review process you can run on every AI-assisted pull request. If you're shipping code that a machine helped write, this is the discipline that keeps you out of a breach postmortem.

Key Takeaways
  • Treat AI code like a junior dev's first PR: helpful, fast, and absolutely requiring review before merge.
  • The top three risks are injection flaws, hardcoded or leaked secrets, and vulnerable/hallucinated dependencies.
  • Run automated gates (SAST, dependency scanning, secret scanning) and a human security read. Neither alone is enough.
  • Watch for "package hallucination": AI invents plausible-sounding libraries that attackers then register and weaponize.
  • Never paste secrets or proprietary code into public AI tools. Prefer local models or self-hosted snippet tools for sensitive work.
  • Codify the checklist into your CI pipeline and PR template so it happens every time, not when someone remembers.

Why AI-Generated Code Security Deserves Its Own Playbook

Human-written code has a built-in speed limit. A developer typing out an authentication flow tends to think about the edge cases as they go, because writing is slow enough to force reflection. AI removes that speed limit. You can generate 200 lines of a payment handler in eight seconds, and the code will look confident and idiomatic. Confidence is not correctness.

The core problem is that large language models optimize for plausible output, not secure output. They learned from public code, and public code is riddled with insecure patterns. When you ask for a file upload handler, the model happily reproduces the same missing MIME-type checks and path-traversal bugs it saw thousands of times on the open web.

There's a good deeper discussion of how these tools actually behave in our comparison of AI coding agents versus autocomplete for developer productivity. The short version: the more autonomous the agent, the more surface area it creates for unreviewed decisions to slip into your codebase.

The Three Failure Modes You'll See Most

  • Silent insecurity: the code works perfectly in the happy path and quietly ignores the attacker path.
  • Confident hallucination: the model invents an API, a config option, or an entire npm package that doesn't exist.
  • Context blindness: the model can't see your other 40,000 lines, so it re-implements auth badly instead of using your existing helper.

A Before/After Example: The Login Endpoint the AI "Fixed"

Let me show you a realistic scenario. Say you ask an assistant to "write a Node.js login route that checks a user's password." Here's the kind of thing you'll often get back:

Before (AI-generated, insecure):

  • Query: SELECT * FROM users WHERE email = '${email}' AND password = '${password}'
  • No parameterization, so it's SQL injection ready. An attacker enters ' OR '1'='1 and logs in as the first user in the table.
  • Passwords compared in plaintext, meaning they're stored in plaintext.
  • No rate limiting, so credential-stuffing runs unimpeded.
  • Error messages distinguish "user not found" from "wrong password", leaking valid emails.

Four separate vulnerabilities in about 12 lines. Every one of them looks harmless in a code review that's only asking "does it work?"

After (hardened by a reviewing human):

  1. Switch to a parameterized query using placeholders so input can never alter the query structure.
  2. Store passwords with bcrypt or argon2, and compare with the library's constant-time verify function.
  3. Add rate limiting: for example, 5 failed attempts per IP per 15 minutes, then a temporary lockout.
  4. Return a single generic message, "Invalid email or password", for every failure case.
  5. Log the failed attempt server-side with a timestamp and source IP for monitoring.

The numbers matter here. In the before version, a single automated tool could enumerate your entire user table in minutes. In the after version, an attacker gets one vague error and a lockout after five tries. Same feature, wildly different blast radius. The AI gave you a starting point. The security review gave you a shippable product.

The Pre-Merge Security Checklist for AI-Generated Code

This is the section to bookmark. Run every AI-assisted change through these gates before it merges. I've ordered them roughly by how often each one catches a real problem.

1. Injection and Input Handling

  • Is every database query parameterized? No string concatenation with user input, ever.
  • Is user input validated against an allow-list, not just a block-list?
  • Is output encoded before rendering to HTML (to stop XSS)?
  • Are shell commands avoided, or at minimum passed as argument arrays rather than a single string?

2. Secrets and Credentials

  • Are there any hardcoded API keys, tokens, or passwords? AI loves inserting "your-api-key-here" and sometimes real-looking placeholder keys.
  • Are secrets pulled from environment variables or a vault?
  • Did anyone paste production secrets into the AI prompt while generating this? (More on that below.)

3. Dependencies and Hallucinated Packages

  • Does every imported package actually exist and is it the one you intended?
  • Run a dependency scanner against the lockfile. Check for known CVEs.
  • Verify install counts and maintenance status. A package with 40 weekly downloads that "does exactly what you need" is a red flag.

4. Authentication and Authorization

  • Does the code check authorization, not just authentication? A logged-in user is not automatically allowed to access resource #42.
  • Are session tokens generated with a cryptographically secure source?
  • Are password hashes using bcrypt/argon2/scrypt, never MD5 or SHA-1?

5. Error Handling and Information Leakage

  • Do error messages leak stack traces, file paths, or SQL to the user?
  • Is sensitive data kept out of logs?
  • Do failures default to "deny" rather than "allow"?

6. Automated Gates in CI

  • SAST (static analysis) runs on the diff.
  • Secret scanning runs on every commit.
  • Dependency/CVE scanning runs on the lockfile.
  • The build fails, not warns, when a high-severity issue appears.

If you maintain WordPress, PrestaShop, or Joomla sites, the same discipline applies to plugin and theme code an assistant helps you write. Our recent breakdowns of the WP Maps Pro admin bypass flaw and the wp2shell attack show how a single missed authorization check turns into full site compromise.

Package Hallucination: The Attack You Didn't Know to Fear

This one deserves its own section because it's newer and genuinely nasty. When an AI assistant confidently suggests import fastjson-parser and that package doesn't exist, most developers assume they made a typo and move on. But attackers have noticed the pattern.

The attack, sometimes called slopsquatting, works like this:

  1. Researchers or attackers query popular AI models thousands of times and log the non-existent package names they hallucinate.
  2. They find that certain fake names get suggested repeatedly and consistently.
  3. They register those exact names on npm or PyPI with malicious code inside.
  4. The next developer who trusts the AI and runs npm install fastjson-parser now has malware in their build.

One 2024 analysis found that some models hallucinated the same fake package name across more than 40% of repeated prompts. That consistency is exactly what makes it exploitable. The fix is simple but non-negotiable: verify every dependency the AI suggests before installing it. Check the registry page, the download count, the source repo, and the last publish date.

AI Coding Assistants Compared on Security Posture

Not all tools handle security the same way, and their defaults matter more than their marketing. Here's how the popular options compare on the criteria that actually affect your risk. Ratings reflect general behavior as of this writing and change with each release.

Tool Built-in vuln filtering Data sent off-device Enterprise privacy controls Best for
GitHub Copilot Basic (vulnerability filter for common patterns) Yes, to cloud Strong (business/enterprise tiers) Teams already in GitHub
Cursor Limited Yes, to cloud Privacy mode available Full-project agentic edits
Amazon Q Developer Good (built-in security scanning) Yes, to AWS Strong (AWS-native) AWS-heavy

Cover image: The Torch Graduate circuit board (bottom) by Chris Whytehead, licensed under BY-SA 3.0 via Openverse.

Recent Posts

View all →

Most Popular Software

View all →

Browse by Platform

View all →