AI Code Generation Security: Best Practices Every Developer Needs


Disclosure: This article may contain affiliate links. We only recommend products we believe in. See how we make money.

AI coding tools are generating an enormous amount of production code in 2026. Vendor surveys disagree on the share. The useful fact is simpler: a lot of merged diffs were typed by a model that does not prioritize security, and the same failure modes keep showing up in public vulnerability write-ups.

This page is a publication-desk checklist for generated diffs — not a scanner bake-off and not a “pitfalls we have seen” lab log. Pair it with how to reduce hallucinations when the model invents a package, with CI/CD pipeline design when the hook should fail the build, and with automated review when you want a first pass on the PR.

Desk note — who this is for / what it’s bad at: Developers who will merge AI-written endpoints, queries, or configs. Bad as a reason to buy a second SAST when Semgrep plus gitleaks already sit in CI unread, and a poor substitute for parameterized queries in the prompt.

What to check before you ship generated code

Listing identity: Semgrep is pattern rules you own. Bandit is Python-only AST checks. Snyk / Dependabot / npm audit read lockfiles for known CVEs. gitleaks / detect-secrets look for tokens. None of them is “AI security.” Buying Snyk does not catch the f-string SQL the model just wrote if Semgrep never got a rule.

Before you merge, or buy another scanner:

  • Parameterized queries beat a scanner. If the prompt did not say “parameterized,” assume concatenation. Ask the model to rewrite; do not hope the SCA invoice notices.
  • Skip a second SAST if CI already fails on Semgrep + gitleaks + a lockfile audit and nobody reads the SARIF. Wire the rules you have. A new vendor logo is not a review policy. The CI guide is where npm ci and the secret hook belong.
  • Do not treat coverage as a security program. A Diffblue-shaped suite that maximizes line hits will not add authz. Tests that snapshot the current implementation encode the bug — see AI unit testing.
  • Fake packages are a registry check. Verify the name on PyPI or npm, then pin. Hallucinated names get registered by attackers. That workflow is on the hallucinations page.
  • Authn ≠ authz. Generated endpoints often “work” in local testing because nobody else called them. Check the caller. Rate limiting on an unauthenticated demo route is the other half of that hole.
  • Do not buy a GPU to “keep code local” and skip review. Local weights still emit MD5 and CORS *. Privacy is the local LLM buy; this page is still the checklist.

The Core Problem

AI code generation models learn from public code. Public code is full of security vulnerabilities. The models learn to reproduce those vulnerabilities with confidence, because the insecure patterns appear frequently in training data.

This doesn’t mean AI tools deliberately write insecure code. It means they default to common patterns, and common patterns are often insecure. SQL queries built with string concatenation, passwords stored in plaintext, API keys hardcoded in source files, these patterns appear constantly in public repositories, and AI tools reproduce them unless you explicitly ask for secure alternatives.

The Most Common AI Security Mistakes

1. SQL Injection via String Concatenation

This is the most frequent security issue in public write-ups of AI-generated code. When you ask an AI to write a database query, it often generates something like this:

# INSECURE - AI commonly generates this
query = f"SELECT * FROM users WHERE username = '{username}'"
cursor.execute(query)

The secure version uses parameterized queries:

# SECURE - always use parameterized queries
query = "SELECT * FROM users WHERE username = %s"
cursor.execute(query, (username,))

AI tools will generate the secure version if you ask, but the insecure version appears first surprisingly often, especially for quick examples and prototypes.

2. Hardcoded Secrets

AI tools routinely generate code with placeholder API keys, database passwords, and tokens hardcoded directly in source files. Developers sometimes replace the placeholders with real values and forget to move them to environment variables.

// AI often generates this pattern
const client = new APIClient({
  apiKey: 'your-api-key-here',  // placeholder that becomes a real key
  secret: 'your-secret-here'
});

The fix is simple: always use environment variables from the start.

const client = new APIClient({
  apiKey: process.env.API_KEY,
  secret: process.env.API_SECRET
});

3. Insufficient Input Validation

AI-generated code frequently assumes well-formed input. When you ask for a function that processes user data, the generated code often skips validation, length checks, type checking, and sanitization.

This matters most for web applications where user input is the primary attack vector. Missing validation can lead to XSS, buffer overflows, path traversal, and other injection attacks.

Practice: After generating any function that handles external input, explicitly ask the AI to add input validation. Or better yet, include “with proper input validation” in your original prompt.

4. Insecure Default Configurations

AI-generated server configurations often use insecure defaults for the sake of simplicity. Public examples keep repeating:

  • CORS policies with * (allow all origins)
  • Debug mode enabled in production configs
  • TLS/SSL disabled or self-signed certificates accepted
  • Overly permissive file permissions
  • Database connections without TLS

These defaults make sense for local development but are security holes in production. The AI doesn’t know which environment the code targets.

5. Weak Cryptography

When you ask AI to implement encryption, hashing, or authentication, it sometimes suggests outdated algorithms. Write-ups still show MD5 for password hashing, DES for encryption, and SHA-1 for integrity checks, all of which are considered broken.

Current recommendations:

  • Password hashing: bcrypt, scrypt, or Argon2
  • Encryption: AES-256-GCM
  • Integrity: SHA-256 or SHA-3
  • Key exchange: X25519

Always verify that AI-generated crypto code uses current algorithms.

6. Missing Authentication and Authorization Checks

AI-generated API endpoints frequently implement the business logic correctly but skip authentication and authorization checks. The AI gives you a working endpoint that anyone can call, without verifying who’s calling it or whether they should have access.

This is especially dangerous because the code works in testing, you just forget that it works for everyone, including attackers.

7. Information Leakage in Error Handling

AI tools often generate detailed error messages that include stack traces, internal paths, database schema details, or configuration information. These details are useful for debugging but should never reach end users.

# INSECURE - AI often generates detailed error responses
@app.errorhandler(500)
def server_error(e):
    return jsonify({"error": str(e), "trace": traceback.format_exc()}), 500

# SECURE - generic error to users, detailed log for developers
@app.errorhandler(500)
def server_error(e):
    app.logger.error(f"Server error: {e}", exc_info=True)
    return jsonify({"error": "An internal error occurred"}), 500

A Security Review Checklist for AI-Generated Code

Before merging any AI-generated code, run through this checklist:

Input handling:

  • Is all external input validated, typed, and length-checked?
  • Are database queries parameterized (not string-concatenated)?
  • Is user input sanitized before display (preventing XSS)?
  • Are file paths validated against traversal attacks?

Authentication and authorization:

  • Does every endpoint check authentication?
  • Does every endpoint verify authorization (role-based access)?
  • Are sessions managed securely (secure cookies, expiration)?

Data protection:

  • Are secrets in environment variables, not source code?
  • Is sensitive data encrypted at rest and in transit?
  • Are modern cryptographic algorithms used?
  • Is PII handled according to relevant regulations?

Error handling:

  • Do error messages hide internal details from users?
  • Are errors logged properly for debugging?
  • Does the application fail securely (deny by default)?

Configuration:

  • Is debug mode disabled for production?
  • Are CORS policies restrictive?
  • Is TLS enabled for all connections?
  • Are file permissions minimally permissive?

Dependencies:

  • Are AI-suggested packages from reputable sources?
  • Are dependency versions pinned?
  • Have dependencies been checked for known vulnerabilities?

Tools That Help

Static Analysis

Run static analysis tools on all AI-generated code. These tools catch many common vulnerabilities automatically:

  • Semgrep, customizable rules, good for catching insecure patterns
  • Bandit (Python), finds common security issues in Python code
  • ESLint security plugins (JavaScript), catches DOM-based XSS, prototype pollution
  • Snyk, dependency vulnerability scanning

AI-Assisted Security Review

Ironically, AI tools are also good at finding security issues in code. After generating code with one AI tool, you can ask another to review it for security vulnerabilities. Claude is particularly strong at identifying subtle security issues in code reviews.

The prompt: “Review this code for security vulnerabilities. Focus on injection attacks, authentication bypass, insecure defaults, and information leakage.”

Pre-Commit Hooks

Set up pre-commit hooks that block obvious security issues:

  • Detect hardcoded secrets with tools like detect-secrets or gitleaks
  • Run linters with security rules enabled
  • Check for known vulnerable dependencies

Organizational Practices

For teams using AI tools at scale, individual vigilance isn’t enough. You need organizational practices:

Secure prompt templates. Create team-wide prompt templates that include security requirements. Instead of “write a login endpoint,” the template should say “write a login endpoint with rate limiting, input validation, parameterized queries, and proper error handling.” The prompt engineering guide is the place to keep those templates from drifting. Team conventions for when AI is allowed at all sit on the workflow page.

Mandatory security review for AI-generated code. Flag AI-generated code in pull requests (some tools do this automatically) and require explicit security review.

Regular security training. Make sure developers understand common vulnerabilities well enough to spot them in AI-generated code. The OWASP Top 10 is a good starting curriculum.

Automated scanning in CI/CD. Run security scanners in your CI pipeline so that vulnerable code gets caught even if it passes human review.

The Bigger Picture

AI code generation security is fundamentally a review problem. The AI generates code quickly, and the human needs to verify it’s secure. The more code AI generates, the more review surface area there is, and the easier it is for security issues to slip through.

The solution isn’t to stop using AI tools, they’re too useful for that. The solution is to build security into the process at every level: secure prompts, automated scanning, human review, and organizational practices. Treat AI-generated code with the same skepticism you’d apply to a pull request from a contractor you’ve never worked with before. The code might be great, but you need to verify.

Security is the one area where “move fast and fix it later” can cost you everything. Take the time to review. Your future self will thank you.

Frequently Asked Questions

Does buying Snyk or another SCA tool make AI-generated code safe?

No. SCA reads lockfiles for known CVEs. It does not rewrite an f-string SQL query or add an authz check the model skipped. Keep Semgrep (or equivalent) rules for injection and secrets, and review the diff.

Why does AI-generated code so often concatenate SQL?

Training data is full of tutorials that build queries with string interpolation. The insecure pattern is common, so it is the default completion unless the prompt says parameterized queries.

Should I install a package an AI suggested without checking the registry?

No. Hallucinated names get registered by attackers. Verify the package on PyPI or npm, check weekly downloads and the GitHub repo, then pin the version. A scanner you have not wired into CI will not save that install.