All articles
Security Fundamentals15 min readJanuary 23, 2026
OWASPChecklistSecurity StandardsBest Practices

The OWASP Top 10 for AI-Generated Code: A 2026 Security Checklist

Map each OWASP Top 10 vulnerability to specific patterns in AI-generated code. A practical checklist for securing your AI-built applications.

Security Guide

The OWASP Top 10 Meets AI-Generated Code

The OWASP Top 10 represents the most critical security risks to web applications. AI coding tools generate vulnerabilities in every single category. This checklist maps each risk to specific AI code patterns.

A01:2021 - Broken Access Control

What it is: Users can act outside their intended permissions.

How AI generates it:

javascript
// AI-generated endpoint - no authorization
app.delete('/api/users/:id', async (req, res) => {
  await User.findByIdAndDelete(req.params.id)
  res.json({ success: true })
})

Checklist:

  • Every endpoint has authentication middleware
  • Authorization checks verify user owns resource
  • Admin functions verify admin role from session
  • No authorization decisions based on client input
Secure pattern:
javascript
app.delete('/api/users/:id', authenticate, async (req, res) => {
  if (req.user.id !== req.params.id && !req.user.isAdmin) {
    return res.status(403).json({ error: 'Forbidden' })
  }
  await User.findByIdAndDelete(req.params.id)
  res.json({ success: true })
})

A02:2021 - Cryptographic Failures

What it is: Weak cryptography or missing encryption for sensitive data.

How AI generates it:

javascript
// AI uses weak hashing
const hash = crypto.createHash('md5').update(password).digest('hex')

// AI stores sensitive data in plain text const user = { email, password: plaintextPassword }

Checklist:

  • Passwords hashed with bcrypt/argon2 (not MD5/SHA1)
  • Sensitive data encrypted at rest
  • TLS enforced for all connections
  • No hardcoded encryption keys
  • Proper IV/nonce usage in encryption
Secure pattern:
javascript
import bcrypt from 'bcrypt'
const hash = await bcrypt.hash(password, 12)

A03:2021 - Injection

What it is: Untrusted data sent to an interpreter as part of a command or query.

How AI generates it:

javascript
// SQL injection
const query = SELECT * FROM users WHERE id = ${userId}

// Command injection exec(convert ${filename} output.png)

// NoSQL injection User.find({ email: req.body.email })

Checklist:

  • All SQL uses parameterized queries
  • ORM methods used instead of raw queries
  • No user input in shell commands
  • NoSQL queries validate input types
  • Template engines auto-escape by default
Secure pattern:
javascript
const query = 'SELECT * FROM users WHERE id = $1'
await db.query(query, [userId])

A04:2021 - Insecure Design

What it is: Missing or ineffective security controls in the design phase.

How AI generates it:

javascript
// Password reset without token verification
app.post('/reset-password', async (req, res) => {
  const user = await User.findOne({ email: req.body.email })
  user.password = req.body.newPassword
  await user.save()
})

Checklist:

  • Password reset uses secure tokens
  • Rate limiting on authentication endpoints
  • Account lockout after failed attempts
  • Secure session management
  • Multi-factor authentication available

A05:2021 - Security Misconfiguration

What it is: Insecure default configurations, incomplete setup, or overly permissive settings.

How AI generates it:

javascript
// Overly permissive CORS
app.use(cors())

// Debug mode in production app.use(errorHandler({ showStack: true }))

// Default credentials const db = connect({ user: 'admin', password: 'admin' })

Checklist:

  • CORS restricts to known origins
  • Error messages don't leak stack traces
  • Debug mode disabled in production
  • Security headers configured (CSP, HSTS, etc.)
  • Default credentials changed
Secure pattern:
javascript
app.use(cors({ origin: process.env.ALLOWED_ORIGIN }))

A06:2021 - Vulnerable Components

What it is: Using components with known vulnerabilities.

How AI generates it:

  • Suggests outdated package versions
  • Copies code with vulnerable dependencies
  • Doesn't specify versions (uses latest with vulnerabilities)
Checklist:
  • Run npm audit regularly
  • Dependabot or Renovate enabled
  • No packages with critical CVEs
  • Lock file committed to repository

A07:2021 - Authentication Failures

What it is: Broken authentication mechanisms.

How AI generates it:

javascript
// Weak password requirements
if (password.length >= 4) { /* accept */ }

// Session fixation req.session.userId = user.id // Without regenerating session

// Credential stuffing enabled (no rate limiting) app.post('/login', async (req, res) => { const user = await authenticate(req.body) // No failed attempt tracking })

Checklist:

  • Strong password requirements enforced
  • Session regenerated on login
  • Rate limiting on authentication
  • Secure session cookie flags
  • JWT tokens expire appropriately

A08:2021 - Data Integrity Failures

What it is: Code and infrastructure that doesn't protect against integrity violations.

How AI generates it:

javascript
// Trusting serialized data from client
const prefs = JSON.parse(req.cookies.userPrefs)

// No integrity check on updates const config = await fetch(configUrl).then(r => r.json())

Checklist:

  • Client-side data validated server-side
  • Signed cookies for sensitive data
  • CI/CD pipeline integrity verified
  • Dependencies from trusted sources

A09:2021 - Security Logging Failures

What it is: Insufficient logging to detect attacks.

How AI generates it:

javascript
// No logging at all
app.post('/login', async (req, res) => {
  const user = await authenticate(req.body)
  if (user) res.json({ token: createToken(user) })
  else res.status(401).json({ error: 'Failed' })
})

Checklist:

  • Failed login attempts logged
  • Access control failures logged
  • Input validation failures logged
  • Logs include timestamp and user context
  • Logs don't contain sensitive data

A10:2021 - Server-Side Request Forgery

What it is: Application fetches URLs without validation.

How AI generates it:

javascript
// Fetching user-provided URL
app.get('/fetch', async (req, res) => {
  const response = await fetch(req.query.url)
  res.send(await response.text())
})

Checklist:

  • URL allowlist for external fetches
  • Block requests to private IP ranges
  • Block requests to cloud metadata URLs
  • Validate URL scheme (http/https only)
Secure pattern:
javascript
const ALLOWED_HOSTS = ['api.trusted.com']
const url = new URL(req.query.url)
if (!ALLOWED_HOSTS.includes(url.hostname)) {
  return res.status(400).json({ error: 'Host not allowed' })
}

Quick Reference Checklist

Print this and check before every deployment:

OWASP TOP 10 PRE-DEPLOY CHECK
=============================
[ ] A01: Auth on all endpoints, authz checks
[ ] A02: Passwords hashed, data encrypted
[ ] A03: Parameterized queries, no injection
[ ] A04: Secure reset flows, rate limiting
[ ] A05: CORS restricted, headers set
[ ] A06: npm audit clean
[ ] A07: Strong passwords, session security
[ ] A08: Server-side validation
[ ] A09: Security events logged
[ ] A10: URL fetching restricted

Automate Your OWASP Checks

Manual checklists work, but automation catches what humans miss. ShipReady scans for all OWASP Top 10 patterns in AI-generated code.

Ready to secure your AI-generated code?

Stop reading about vulnerabilities. Start fixing them.

Start Scanning Free