# Find security vulnerabilities in your code with AI

URL: https://agentvera.dev/en/blog/find-security-vulnerabilities-with-ai/ · Published: 2026-10-27

Audit your own code with an AI coding agent: OWASP classes, secret and dependency scans, /security-review, false positives, and fixes backed by a regression test.

**In short:**

- Run the cheap, deterministic scanners first (gitleaks, npm audit or pip-audit, Semgrep), then point a coding agent at one vulnerability class at a time and ask it to trace real data flow.
- In Claude Code, /security-review checks the changes on your branch against the default branch; the security-guidance plugin reviews code while Claude writes it.
- Treat every finding as a claim: ask for file:line, the input source and a reachable path, fix it with a regression test that fails first, and rotate any leaked secret before cleaning history.

To find security vulnerabilities in your code with AI, run the fast deterministic scanners first (secrets, dependencies, static rules), then give a coding agent one vulnerability class at a time and ask it to trace how untrusted input moves through your code. Treat each finding as a claim to verify, fix it with a regression test, and keep the agent away from real secrets the whole time.

This guide is about auditing **your own code**, defensively. If you want to know how to keep the agent itself from doing damage (prompt injection, destructive commands, malicious MCP servers), read [AI coding agent security](/en/blog/ai-coding-agent-security/ "AI coding agent security") first; this post assumes those safeguards are in place. Tool names and commands below follow the official documentation as of October 2026.

## What an AI audit is good at, and what it isn’t

Static scanners and coding agents find different bugs, which is why you want both.

| | Deterministic scanners | Coding agent |
| --- | --- | --- |
| Strength | Known patterns, known vulnerable package versions, secret formats | Logic: who may call this route, where this value comes from, what a check forgot |
| Weakness | Miss business logic; noisy on safe patterns | False positives, missed issues, different answers on each run |
| Cost | Seconds, repeatable | Tokens, slower, not repeatable |
| Best use | CI gate on every change | Targeted audit of risky areas and new code |

An agent shines on things like an endpoint that checks you are logged in but never checks that the order you are reading is yours. No regex sees that. On the other hand, an agent will not reliably notice that `lodash` in your lockfile is three years old; `npm audit` will.

What neither does: test your running system. An agent reads the source in your checkout. Misconfigured cloud storage, a firewall rule or a leaked token in a chat log are out of its view.

## Before you start: a safe setup

A security audit is a read-heavy task, so set it up that way.

- **Work on a branch or a [git worktree](/en/blog/git-worktree-parallel-agents/ "Git worktrees for parallel agents").** The audit and the fixes should be easy to review and easy to throw away.
- **Start read-only.** In Claude Code, use plan mode (Shift+Tab or `/plan`) for the audit itself; in Codex, `/permissions` → Read Only or `--sandbox read-only`. Switch to edits only when you fix.
- **Keep secrets out of reach.** Don’t paste keys, tokens or `.env` contents into a prompt, ever. If the agent needs to know a variable exists, the name is enough. A `.env.example` with fake values is what it should read.
- **Use development credentials.** If the agent runs your tests, those tests should talk to a local or staging database with throwaway keys, never production.

## Step 1: run the deterministic scanners

These take seconds and give the agent concrete leads. All of them are free to run locally.

```bash
# Secrets in git history and in the working tree (gitleaks v8.19+)
gitleaks git -v .
gitleaks dir -v .

# Known-vulnerable dependencies
npm audit --audit-level=high
pip-audit -r requirements.txt

# Static analysis rules for your languages
semgrep scan --config auto
```

A few notes from the official docs:

- **gitleaks** split its old `detect` command into `git` (scan commits) and `dir` (scan files) in v8.19.0; the old commands still work but are hidden from help.
- **npm audit** `--audit-level` only changes the exit code, not the report. `npm audit fix` runs a real install; `npm audit fix --force` may install SemVer-major updates, so don’t run it blindly.
- **pip-audit** with no arguments audits the current Python environment; `-r` audits a requirements file.
- **Semgrep** `--config auto` fetches rules tailored to your project from the Semgrep Registry, so it needs network access. Add `--error` to exit with 1 when there are findings, which is what you want in CI.

Save the output to a file. In step 3 you’ll hand it to the agent instead of retyping it.

## Step 2: audit one vulnerability class at a time

“Find security bugs in this repo” gets you a shallow list. A focused prompt per class gets you real analysis. The [OWASP Top 10:2025](https://top10.owasp.org/2025 "OWASP Top 10:2025") is a good map; these are the classes worth auditing first in a typical web app:

| Class | What to ask the agent to trace | Typical sign |
| --- | --- | --- |
| Broken access control | Every route that reads or changes a record: does it check the record belongs to the caller? | `findById(req.params.id)` with no owner or tenant filter |
| Injection (SQL, shell, XSS) | Every place user input reaches a query, a shell command or HTML | String concatenation into SQL, `exec` with input, raw HTML rendering |
| Authentication failures | Login, session, password reset and token handling | Reset tokens that never expire, missing rate limit on login |
| SSRF | Every server-side request whose URL comes from the user | `fetch(req.body.url)` with no allow list |
| Secrets in the repo | Hardcoded keys, tokens in config, credentials in tests | Strings that look like keys; gitleaks will be more reliable |
| Supply chain | Dependencies, install scripts, CI workflow permissions | Unpinned actions, broad `permissions:` in workflows |

A prompt that works, in plan mode:

```text
Audit this repository for broken access control. Do not edit files.

1. List every HTTP route that reads, updates or deletes a record by ID.
2. For each one, find where the caller's identity comes from and whether
   the query is limited to records the caller owns (user or tenant).
3. Report only routes where you can show the missing check.

For each finding give: file:line, the route, where the ID comes from,
why the existing middleware does not cover it, and a severity
(high/medium/low). If you are unsure, say so instead of guessing.
```

Repeat the same shape for injection, auth and SSRF. One class per conversation keeps the [context window](/en/glossary/context-window/ "What is a context window") focused, and you can run them in parallel in separate sessions.

For injection, it helps to tell the agent what “safe” looks like in your stack, so it doesn’t flag every query:

```text
We use parameterized queries through db.query(sql, params) everywhere.
Find any place that builds SQL, shell commands or HTML from request
data without going through db.query params, execFile with an argument
array, or the template engine's escaping. Ignore code under tests/.
```

## Step 3: use the built-in security reviews

Several agents now ship a security review you don’t have to write yourself.

**Claude Code `/security-review`.** The official command reference describes it as analyzing the changes on your current branch for security vulnerabilities: it reviews the diff between your branch and the default branch of `origin` and looks for risks like injection, auth issues and data exposure. It needs an `origin` remote. It covers your branch’s changes only, so run it before you open a pull request. Anthropic’s `claude-code-security-review` repository explains how to customize it: copy its `security-review.md` into `.claude/commands/` and add your own rules, for example which patterns are safe in your codebase.

**Claude Code security-guidance plugin.** Installed with `/plugin install security-guidance@claude-plugins-official`, it reviews code while Claude writes it: a pattern check on each edit (things like `eval(`, `child_process.exec`, `.innerHTML =`), a background security review of each turn’s diff, and a deeper review when Claude commits. You can add project rules in `.claude/claude-security-guidance.md`. The docs are clear that it doesn’t block writes and can miss issues; it is one layer.

**Codex `/review`.** Codex’s review command (and `codex review --uncommitted` or `--base main` from the shell) is a general code review. Ask it explicitly to focus on security if that’s what you want.

**Gemini CLI security extension.** Installed with `gemini extensions install https://github.com/gemini-cli-extensions/security`, it adds `/security:analyze` for the changes on your branch and `/security:scan-deps`, which checks dependencies with OSV-Scanner.

For code you already have, rather than a branch’s changes, use the class-by-class prompts from step 2. You can also feed the scanner output in:

```text
Here is the output of semgrep and npm audit in scan-results.txt.
For each finding, check whether it is reachable from user input in
this codebase. Mark each as confirmed, likely false positive or
needs a human, with a one-line reason. Do not edit files.
```

## Step 4: separate real findings from false positives

AI security reviews are confident in tone whether they are right or not. Ask for evidence, not verdicts:

- **Source:** where does the untrusted value enter? A request body, a query string, a file upload, a webhook?
- **Path:** which functions does it pass through to reach the risky call? Ask for the chain with file:line for each hop.
- **Guard:** what validation, escaping or authorization sits on that path, and why doesn’t it cover this case?
- **Reachability:** is the route exposed? A finding in a dead admin script is not the same as one in a public API.

Then get a second opinion. A fresh session, or better a different model, should check high-severity findings before anyone writes a fix. Give it the finding and the code, not the first agent’s reasoning, so it doesn’t simply agree. [AI code review](/en/blog/ai-code-review/ "AI code review") describes how to weigh findings and keep that loop bounded.

Common false positives to expect: SQL built from constants only, HTML that passes through a framework’s automatic escaping, test fixtures with fake keys, and server-side requests to a fixed internal URL. Write the safe patterns into `CLAUDE.md` or `AGENTS.md` so later audits stop flagging them.

## Step 5: fix with a regression test

A security fix without a test tends to come back. Ask for the test first:

```text
Fix the missing ownership check in GET /api/orders/:id (finding #2).

1. First write a test where user A requests user B's order and expect
   a 404. Run it and show me that it fails.
2. Then add the check in the smallest way that fits our existing
   middleware. Don't change unrelated code.
3. Run the full test suite and show me the diff.
```

The failing-then-passing test proves the bug existed and that the fix covers it. Keep each fix in its own commit with a clear message, so the history explains what was wrong. For the general habit of test-first fixes, see [debugging code with AI](/en/blog/debug-code-with-ai/ "Debug code with AI").

The same discipline applies to dependency findings: upgrade one package at a time, run the tests, read the changelog for breaking changes. A mass `npm audit fix --force` is how an audit turns into an outage.

## If you find a real secret in the repo

This is the one case where the order of steps matters:

1. **Rotate the secret first.** Revoke the key at the provider and issue a new one. Once a secret has been pushed, assume it is compromised; deleting the file doesn’t un-leak it.
2. **Move the new secret into your secret manager or environment**, not back into the code.
3. **Then clean up**: remove it from the code, and decide with your team whether to rewrite history. Rewriting history doesn’t help if the key wasn’t rotated.
4. **Prevent the next one** with a pre-commit hook. gitleaks documents this `.pre-commit-config.yaml` entry:

```yaml
repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.24.2
    hooks:
      - id: gitleaks
```

Let the agent help with steps 2 to 4, but never by pasting the secret into the conversation. “The Stripe key in src/config.ts must move to an environment variable called STRIPE_SECRET_KEY” is all it needs.

## Make it continuous

A one-time audit decays as soon as new code lands. Put the deterministic checks in CI and keep the AI review for pull requests:

```yaml
# .github/workflows/security.yml (excerpt)
- run: npm audit --audit-level=high
- run: semgrep scan --config auto --error
```

For an AI pass on every pull request, Anthropic’s `anthropics/claude-code-security-review` GitHub Action comments findings on the PR. Its required input is `claude-api-key`; optional inputs include `comment-pr`, `exclude-directories` and `false-positive-filtering-instructions`. If you already run Claude in GitHub Actions, [Claude Code GitHub Actions](/en/blog/claude-code-github-actions/ "Claude Code GitHub Actions") covers setup and secrets handling.

## Doing it with AgentVera

AgentVera is a desktop app for macOS, Windows and Linux that runs Claude Code, Codex, Gemini CLI and other CLI agents side by side in real terminals. For security audits, that makes a few setups easy:

- **[Workspace](/en/features/workspace/ "Workspace"):** put a read-only auditor (permission set to Ask) next to a fixer working in a worktree, and a third pane with a different CLI as the second opinion. Each agent keeps its own permission level.
- **[Code review](/en/features/code-review/ "Code review"):** turn on review at the end of each turn in the project settings, and a Claude model you choose reviews the fixer’s changes; findings come with severity and a file:line link and can go back to the agent, at most two rounds in a row.
- **[Review inbox](/en/features/review-inbox/ "Review inbox"):** finished work waits as cards, and risky changes are flagged: auth and security code, dependency files, CI and infra files, `.env` and changes with no tests.
- **[Verify](/en/features/verify/ "Verify") (Pro and Team):** a separate read-only verifier checks the result against the criteria in your request, such as “a regression test exists and fails without the fix”.
- **[Agents in Docker](/en/features/agents-in-docker/ "Agents in Docker"):** run Claude Code or Codex in a container that only sees the project folder, so files and SSH keys elsewhere on your machine stay out of reach during an audit.
- **[Checkpoints](/en/features/checkpoints-and-replay/ "Checkpoints and replay"):** each turn is snapshotted, so a fix that goes wrong is one click to undo.

The grid, worktrees, code review and Docker agents are on the free plan. [Download AgentVera](/en/download/ "Download AgentVera") and run your first audit on a branch.

## Common mistakes

- **Asking for “all security issues” at once.** You get a generic checklist. Audit one class at a time.
- **Fixing before verifying.** A false positive “fixed” adds code that nobody understands. Get evidence first.
- **Pasting secrets to “check if they’re valid”.** Never. Rotate instead.
- **Running `npm audit fix --force` in an agent loop.** Major upgrades break things in ways that look unrelated.
- **Treating a clean AI review as a guarantee.** It means the agent didn’t find anything this time. Keep the scanners in CI.
- **Letting the auditor edit.** Keep the audit read-only and the fixes in a separate, reviewed step.

## Wrapping up

Start with gitleaks, your dependency auditor and Semgrep. Then audit one OWASP class at a time with a read-only agent, asking for file:line evidence and a reachable path. Run `/security-review` (or your agent’s equivalent) before each pull request, have a second session check the serious findings, and fix each one with a regression test that fails first. If a secret leaks, rotate it before anything else. When you’re ready to put agents to work on the fixes, [AI pair programming](/en/blog/ai-pair-programming/ "AI pair programming") shows how to keep yourself in the navigator’s seat. If you are new to all this, [learn to code with AI](/en/blog/learn-to-code-with-ai/ "Learn to code with AI") is a gentler place to start.

## Frequently asked questions

**Can an AI coding agent find security vulnerabilities?** Yes, especially logic flaws that pattern-based scanners miss, such as a missing ownership check on an API route. It also reports false positives and misses things, so treat its output as leads to verify, and keep running deterministic scanners alongside it.

**What does /security-review do in Claude Code?** It analyzes the changes on your current branch for security vulnerabilities, comparing against the default branch of the origin remote, and reports risks such as injection, auth issues and data exposure. It needs an origin remote. It reviews the diff, not the whole repository.

**Should I give the agent my .env file so it can check my secrets?** No. Never paste real secrets into a prompt. Use a secret scanner such as gitleaks to find them, keep .env out of what the agent reads, and if a real key was ever committed, rotate it first and then clean the history.

**How do I deal with false positives from an AI security review?** Ask for evidence for each finding: the file and line, where the untrusted input comes from, the path that reaches the risky call and why existing validation does not cover it. Have a fresh session or a different model verify high-severity findings before you change code.

**Is an AI security audit a replacement for a penetration test?** No. It reads source code in your checkout and finds likely flaws early and cheaply. It does not test your running system, its configuration or its infrastructure. For anything handling money, health or personal data, add a professional review.

---

**About AgentVera.** AgentVera is a desktop app for macOS, Windows and Linux, built by Solviera Teknoloji. It runs 18 AI coding agents (Claude Code, Codex, Gemini CLI, Copilot, Cursor, Antigravity, opencode, Hermes, Qwen Code, Kimi Code, Kiro, Amp, Droid, Goose, Vibe, Crush, Aider, Cline) side by side, per project, in real terminals with the user's own CLI installs and logins. The free plan has unlimited agents. Download: https://agentvera.dev/en/download/ · Pricing: https://agentvera.dev/en/pricing/
