Most web applications contain at least one vulnerability from the OWASP Top 10. A typical security audit takes 2-3 weeks and costs upward of $10,000. An LLM can compress the initial audit down to a few hours because it scans code for patterns rather than specific CVEs.
Below are 15 vulnerabilities found while auditing production code with Claude. Each includes the vulnerable code, the fixed version, and a prompt to reproduce the finding. Classification follows OWASP Top 10 (2021). Order reflects frequency of occurrence: most common first.
Methodology: how to run an AI security audit
The audit consists of three passes. First, a broad scan: the LLM receives the entire project and looks for vulnerability patterns. Second, deep analysis: each identified pattern is verified in context (middleware, ORM, framework). Third, verification: manual review of every finding, because LLMs produce false positives.
Prompt for the broad scan:
Perform a security audit of this code. For each finding, include:
1. CWE ID and name
2. OWASP Top 10 category
3. Severity (Critical/High/Medium/Low)
4. The vulnerable code snippet
5. Attack vector -- exactly how an attacker would exploit this
6. Fixed code
Ignore stylistic comments. Focus on security only.
Start with injection attacks, then broken access control, then the rest.
This prompt works because it defines the output structure and prioritizes categories. Without explicit instructions, the LLM mixes critical vulnerabilities with remarks about email validation.
More on structured AI code review: .
A08:2021 -- Software and Data Integrity Failures
15. Prototype Pollution via deep object merge
// Vulnerable: recursive merge without protection
function deepMerge(target: any, source: any): any {
for (const key of Object.keys(source)) {
if (typeof source[key] === 'object' && source[key] !== null) {
target[key] = deepMerge(target[key] || {}, source[key]);
} else {
target[key] = source[key];
}
}
return target;
}
app.put('/api/settings', authMiddleware, async (req, res) => {
const currentSettings = await getSettings(req.user.id);
const merged = deepMerge(currentSettings, req.body);
await saveSettings(req.user.id, merged);
res.json(merged);
});
Attack vector: PUT /api/settings with body {"__proto__": {"isAdmin": true}}. After the merge, every object in the application inherits isAdmin: true.
function deepMerge(target: any, source: any): any {
for (const key of Object.keys(source)) {
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
continue;
}
if (typeof source[key] === 'object' && source[key] !== null && !Array.isArray(source[key])) {
target[key] = deepMerge(target[key] || {}, source[key]);
} else {
target[key] = source[key];
}
}
return target;
}
Three keys are blocked: __proto__, constructor, prototype. In production, prefer battle-tested libraries: lodash merge starting from 4.17.21 is protected, or use structuredClone for copying.
Prompts for each OWASP category
A broad scan catches obvious vulnerabilities. Deep analysis requires specialized prompts by category.
Injection (A03):
Find all places where user input reaches SQL, NoSQL,
LDAP, OS commands, or ORM raw queries without parameterization.
Consider: query params, request body, headers, cookies, file uploads.
Check ORM methods that use raw SQL.
Access Control (A01):
Review every API endpoint: is there a check that the current user
owns the requested resource? Find endpoints that verify authentication
but not authorization. Pay attention to admin endpoints, bulk
operations, export/download.
SSRF and Insecure Design (A04):
Find all places where the server makes HTTP requests to a URL from
user input. Check: is it possible to reach internal services
(metadata API, localhost, private networks)? Is there URL validation,
DNS rebinding protection, redirect restrictions?
Authentication (A07):
Review the authentication mechanism: password storage (bcrypt/argon2?),
JWT (algorithm pinned? refresh tokens present?), sessions (httpOnly?
secure? sameSite?), rate limiting on login/register/reset-password.
Find endpoints without authentication that should be protected.
Automation: CI pipeline for security audit
Manual audit provides depth. Automated audit in CI provides consistency. Combining both closes most vulnerabilities before production.
# .github/workflows/security-audit.yml
name: AI Security Audit
on:
pull_request:
paths:
- 'src/**'
- 'api/**'
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run SAST
run: |
npx semgrep --config=p/owasp-top-ten src/
- name: Check dependencies
run: npm audit --audit-level=high
- name: Check secrets
run: npx gitleaks detect --source=. --no-git
Semgrep covers OWASP Top 10 with minimal false positives. npm audit catches vulnerable dependencies. Gitleaks finds committed secrets. LLM audit runs separately, at pre-merge review.
Quick audit checklist
Before each release:
All user inputs are parameterized (SQL, NoSQL, shell)
Every endpoint checks resource ownership, not just authentication
File operations are confined to the base directory (path traversal)
Update operations accept a whitelist of fields (mass assignment)
JWT algorithm is pinned in code, not taken from the token
No secrets in source code or build variables
CORS origin is restricted to a whitelist, not*
Error messages do not expose internals (stack trace, SQL)
External URLs go through DNS validation (SSRF)
Financial operations run in transactions withFOR UPDATE
Token comparison usestimingSafeEqual, not===
Rate limiting on auth endpoints + account lockout
Deep object merges are protected against prototype pollution
CI pipeline includes SAST (semgrep) and dependency audit
LLM security review on every PR touching API/auth
Each item corresponds to one of the 15 vulnerabilities above. If any item fails, it maps to a concrete vulnerability with a known attack vector.
Need help with AI-powered security audits? I help startups build AI products and automate processes — belov.works.
FAQ
Can an LLM replace a professional penetration tester?
No. LLMs excel at pattern recognition across large codebases and surface the majority of OWASP Top 10 issues in hours, but they produce false positives and miss logic-level flaws that require understanding business context. A manual security review by a specialist is still necessary for critical systems — AI compresses the preparation phase and handles the repeatable patterns, freeing the human reviewer for the nuanced findings.
Which model performs best for security auditing — GPT-4o, Claude, or Gemini?
In practice, Claude and GPT-4o produce comparable results for security audits when given a structured prompt. The model matters less than the prompt quality and the completeness of the code submitted for review. What consistently degrades results: sending partial snippets instead of full files, omitting framework and ORM context, and skipping the verification pass against false positives.
How do I handle secrets that were already committed to the repository?
Finding and removing the secret from code is not enough — it remains in Git history. Rotate the exposed credential immediately, then use git filter-repo (not the deprecated git filter-branch) to purge it from all commits. After that, set up pre-commit hooks with Gitleaks or detect-secrets to prevent future commits. Treat any secret that touched a repository as compromised, regardless of how briefly.
SOCIAL SHARE CARD GENERATOR