On this page
  1. Why AI assistants ship vulnerable code
  2. 1. SQL injection via string concatenation
  3. 2. Hardcoded secrets
  4. 3. Missing access control
  5. 4. Path traversal in file downloads
  6. 5. SSRF via user-supplied URLs
  7. 6. Open redirect in login flows
  8. 7. Missing security headers
  9. 8. Prompt injection in LLM-powered features
  10. 9. Dependency confusion / malicious packages
  11. 10. Weak or missing authentication
  12. 11. No rate limiting
  13. 12. Exposing internal errors to users
  14. 13. No CSRF protection
  15. 14. Clickjacking vulnerability
  16. 15. Non-human identity sprawl
  17. Checklist
  18. FAQ
    1. Does my AI assistant really write vulnerable code by default?
    2. How do I catch these before they ship?
    3. Which of these is most dangerous?
    4. Can’t I just ask the AI to “write secure code”?
  19. Related topics
  20. Sources
guide

The 15 Security Failures Your AI Coding Assistant Ships by Default

AI coding assistants default to SQL injection, hardcoded secrets, missing access controls, and 12 other security failures. Here's every one, with the fix and the linked guide.

Quick answer

  • AI coding assistants default to vulnerable patterns because they learned from public code.
  • The 15 most common AI-generated security failures are below, each with the fix and linked guide.
  • Catch them in code review and CI, not in production.

Why AI assistants ship vulnerable code

AI coding assistants are trained on public repositories — tutorials, Stack Overflow answers, and open-source projects. Public code prioritizes “it works” over “it’s secure.” Tutorials skip auth for brevity. Stack Overflow answers omit validation. Open-source projects ship known CVEs. The model learns these patterns and faithfully reproduces them.

The result: your AI coding assistant writes code that works, but ships vulnerabilities by default. Below are the 15 most common ones, what they look like, and how to fix them.


1. SQL injection via string concatenation

What the AI writes:

query = f"SELECT * FROM users WHERE email = '{email}'"

The fix: Parameterized queries. Always.


2. Hardcoded secrets

What the AI writes:

OPENAI_API_KEY = "sk-abc123def456"
DATABASE_URL = "postgres://user:password@localhost/db"

The fix: Environment variables, never in source code. Rotate anything already committed.


3. Missing access control

What the AI writes: An endpoint that returns any user’s data when you change the ID in the URL. No check that the requesting user is authorized.

GET /api/users/123 → returns user 123's data
GET /api/users/456 → also returns data, with no auth check

The fix: Verify the caller owns or is authorized for every resource on every endpoint.


4. Path traversal in file downloads

What the AI writes:

filepath = os.path.join("/uploads", filename)
return open(filepath).read()

A request for ../../../../etc/passwd walks up out of the uploads directory.

The fix: Resolve the final absolute path and verify it stays inside the allowed directory — or use ID-based lookups instead of filenames.


5. SSRF via user-supplied URLs

What the AI writes: An endpoint that fetches a user-supplied URL — to generate a preview, download an avatar, or scrape a page — with no validation of the target.

The fix: Validate the URL against an allowlist, block internal IP ranges, and never fetch URLs the user supplies directly.


6. Open redirect in login flows

What the AI writes:

/login?redirect=https://evil.com
→ after login, redirects to evil.com

The fix: Validate redirect URLs against an allowlist of trusted domains, or use relative paths.


7. Missing security headers

What the AI writes: An HTML page with no CSP, no HSTS, no X-Frame-Options, no X-Content-Type-Options.

The fix: Add security headers at the server or CDN level. CSP is the most important — it blocks XSS even when your code has injection flaws.


8. Prompt injection in LLM-powered features

What the AI writes: An endpoint that sends user input directly to an LLM with no sanitization:

system: "You are a helpful assistant"
user: [USER INPUT HERE]

The fix: Separate user data from instructions, validate output, and never give the LLM tools that can be triggered by user input alone.


9. Dependency confusion / malicious packages

What the AI writes:

$ pip install some-package
$ npm install some-library

Without checking whether the package is legitimate, whether it’s the one you meant, or whether it has known vulnerabilities.

The fix: Audit dependencies before adding them. Use lockfiles. Generate an SBOM. Watch for AI-hallucinated package names.


10. Weak or missing authentication

What the AI writes: JWTs with alg: none, passwords hashed with SHA-256 instead of bcrypt, sessions with no expiry, OAuth flows with no state parameter.

The fix: Use bcrypt/argon2 for passwords, validate JWT algorithms, add session expiry, and implement OAuth correctly.


11. No rate limiting

What the AI writes: A login endpoint, an API route, or a password reset flow with no rate limiting. Brute-force attacks and credential stuffing are trivially easy.

The fix: Add rate limiting per IP, per user, per endpoint. Start restrictive and loosen as needed.


12. Exposing internal errors to users

What the AI writes:

try:
    result = db.query(...)
except Exception as e:
    return {"error": str(e)}, 500

Stack traces, SQL errors, and file paths leak through the API response.

The fix: Log the full error internally; return a generic message to the client.


13. No CSRF protection

What the AI writes: Forms with no CSRF token, state-changing GET requests, cookies with SameSite not set.

The fix: Add CSRF tokens to state-changing forms. Set cookies to SameSite=Lax. Use framework CSRF protection.


14. Clickjacking vulnerability

What the AI writes: Pages with no X-Frame-Options or CSP frame-ancestors — the page can be embedded in an invisible iframe on an attacker’s site.

The fix: X-Frame-Options: DENY or CSP frame-ancestors 'none'.


15. Non-human identity sprawl

What the AI writes: A new API key, service account, or CI/CD token for every feature — with no rotation, no least privilege, and no audit trail.

The fix: Rotate credentials on a schedule. Enforce least privilege — every key gets the minimum permissions it needs. Audit what exists.


Where this bites vibecoders

All 15 failures ship in AI-generated code by default. The assistant isn’t malicious — it just reproduces insecure patterns that dominate its training data. You are the security review. After every AI-generated feature, run this checklist: (1) are queries parameterized? (2) are secrets out of the code? (3) is access checked on every endpoint? (4) are there security headers? Four questions, thirty seconds, saves a breach.

Checklist

  • All database queries use parameterized statements
  • Zero hardcoded secrets in source code
  • Every endpoint verifies the caller is authorized
  • File paths resolved and validated, not built from raw input
  • User-supplied URLs validated against an allowlist
  • Redirect targets validated against an allowlist
  • Security headers applied (CSP, HSTS, X-Frame-Options)
  • No user input passed directly to LLM system prompts
  • Dependencies audited (no hallucinated packages, no known CVEs)
  • Passwords hashed with bcrypt/argon2, JWTs validated
  • Rate limiting on login, API, and sensitive endpoints
  • Internal errors logged, not returned to clients
  • CSRF tokens on all state-changing requests
  • X-Frame-Options: DENY or CSP frame-ancestors
  • NHIs rotated, least-privileged, and audited

FAQ

Does my AI assistant really write vulnerable code by default?

Yes. AI models are trained on public code, which overwhelmingly favors “works” over “secure.” The assistant will confidently generate SQL queries with string concatenation, hardcode API keys, skip authorization checks, and use outdated crypto — because that’s what training data looks like. It’s not malicious, just pattern-matched to insecure defaults.

How do I catch these before they ship?

Three habits: (1) run a SAST scanner in CI, (2) review every AI-generated endpoint for auth, input validation, and parameterized queries, and (3) never accept a multi-file AI output without reading every changed line. The linked guides above explain how to fix each specific failure.

Which of these is most dangerous?

SQL injection — it gives an attacker full read/write access to your database. Prompt injection is a close second if your app uses LLMs in any way. Fix these two first, then work through the rest.

Can’t I just ask the AI to “write secure code”?

You can, and it helps — but it’s not reliable. The AI will add some security but miss others. It doesn’t have a security model; it has pattern-matching. “Write secure code” adds try/except and a password hash but still skips CSRF tokens and rate limiting. Use the checklist above; don’t trust the prompt alone.


Sources

Share: