Your AI coding agent just shipped a pull request that looks clean, passes all tests, and reads like code you’d be proud to write yourself. It’s also hiding a broken WebSocket authentication handler. New March 2026 research found that 87% of pull requests generated by Claude Code, OpenAI Codex, and Google Gemini contained at least one security vulnerability. AI coding agent security vulnerabilities aren’t hypothetical; they’re merging to your main branch right now. This guide cuts through the noise and gives you a concrete, five-layer CI/CD checklist — with copy-paste configurations — built specifically around the vulnerability classes these agents repeatedly produce.
The 87% Problem: What the DryRun Security Report Actually Found
In March 2026, DryRun Security published The Agentic Coding Security Report — the most empirically specific study of AI agent code quality to date. The findings are hard to ignore: 26 of 30 pull requests generated by Claude Code, OpenAI Codex, and Google Gemini contained at least one security vulnerability. Across 38 scans, researchers logged 143 total issues.
The number that should stick with you isn’t 87%. It’s the root cause.
Agents weren’t producing novel, exotic attack surfaces. They were consistently failing to wire up security logic they had already written.
REST authentication middleware would exist in the codebase — correct, functional — and never get mounted on WebSocket upgrade handlers. OAuth flows would be implemented without the state parameter. JWT libraries would be initialized with insecure defaults the agent never overrode.
“The root cause is systemic, not model-specific: agents build correct security middleware then fail to apply it consistently.” — DryRun Security, March 2026
This matters because no regex-based SAST tool catches a logic gap. Your scanner doesn’t know that `authMiddleware` exists and is simply missing from the WebSocket route.
The data also reveals agent-specific failure patterns that generic guidance ignores. Among the three agents tested, Claude produced the highest number of unresolved high-severity flaws in the final builds — 13 issues, including a unique 2FA-disable bypass. Codex finished with the fewest final issues. Gemini’s failure profile differs again.
A checklist treating all three agents identically misses this nuance entirely.
And this isn’t isolated research. A 2025 Veracode study found that only 55% of AI-generated code across 80 tasks in four languages was fully secure — 45% contained flaws, with Java hitting a 72% failure rate. Meanwhile, 84% of developers now use AI coding tools, with 51% using them daily (Stack Overflow Developer Survey 2025, 49,000 respondents).
Widespread adoption plus high defect rates equals a growing attack surface in production code. The question is whether your pipeline is equipped to catch it.
AI Coding Agent Security Vulnerabilities: 5 Recurring Classes
Before you can scan for something, you need to know what you’re scanning for. The DryRun report identified five vulnerability classes that appeared across agents with notable consistency:
- Broken access control — the top OWASP category, reproduced faithfully by agents that implement permission checks inconsistently across routes
- Missing WebSocket authentication — REST middleware applied correctly, never extended to the WebSocket upgrade path
- OAuth state parameter omission — OAuth flows implemented without CSRF protection baked in
- Insecure JWT defaults — libraries initialized without explicit algorithm pinning, expiry enforcement, or signature verification
- Unauthenticated destructive endpoints — DELETE and PATCH routes created without auth guards because the agent treated them as internal utility routes
A 2026 study of 534 AI-generated code samples across six LLMs added more texture: SSRF (CWE-918) was the single most frequently generated vulnerability, and injection-class weaknesses accounted for one-third of all confirmed findings.
Here’s the part that should change how you configure your pipeline: 78% of confirmed vulnerabilities in that study were caught by exactly one scanner. If you’re running a single SAST tool, you’re statistically likely to miss the majority of what’s actually present. Multi-tool coverage isn’t a luxury when AI agents are writing your code — it’s a requirement.
With the threat model established, here’s how to build the five-layer system that catches these.
Layer 1 — Pre-Commit Gates: Stop Secrets Before They Leave Your Machine
The first line of defense never touches your CI/CD server. It runs before a commit is created.
Secret detection
Install [gitleaks](https://github.com/gitleaks/gitleaks) or [detect-secrets](https://github.com/Yelp/detect-secrets) as a pre-commit hook. AI agents frequently inline API keys, connection strings, and tokens in configuration files — and GitHub detected more than 39 million leaked secrets in public repositories in 2024, with 61% of organizations exposing cloud credentials (Wiz, State of Code Security Report 2025).
“`yaml
# .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
hooks:
- id: gitleaks
“`
Dependency pinning
AI agents pull in dependencies without auditing them. Add `pip-audit` (Python), `npm audit` (Node), or `trivy fs` (polyglot) to your pre-commit hooks to catch known CVEs before code is staged.
The goal at this layer is simple: nothing containing a secret or a CVE-flagged dependency should ever reach a PR.
Layer 2 — Per-PR SAST: Configuring Scanners for AI-Specific Auth and Injection Patterns
Standard SAST configurations were tuned for human-written code. They miss the logic gaps AI agents produce — and they miss even more when you’re running only one of them.
Why per-PR scanning matters
DryRun’s own methodology showed why end-of-sprint scanning fails: some vulnerabilities were introduced in PR 1 and carried unresolved through to the final build. Scanning per-PR catches these at the point of introduction, before they compound across five more features and three more contributors.
Semgrep: Auth-specific rulesets
Semgrep’s [p/jwt](https://semgrep.dev/p/jwt) and [p/owasp-top-ten](https://semgrep.dev/p/owasp-top-ten) rulesets cover most of the JWT misconfiguration and broken access control patterns from the DryRun report. Add them to your GitHub Actions workflow:
“`yaml
# .github/workflows/semgrep.yml
name: Semgrep
on: [pull_request]
jobs:
semgrep:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: semgrep/semgrep-action@v1
with:
config: >
p/jwt
p/owasp-top-ten
p/secrets
“`
SonarQube: Data-flow coverage
Semgrep excels at pattern matching; SonarQube adds data-flow analysis that catches issues like “auth function defined but never called on this route.” SonarCloud’s free tier integrates directly with GitHub PRs and provides the complementary coverage your second scanner needs.
Given that 78% of confirmed vulnerabilities are caught by only a single tool, Semgrep (pattern-based) plus SonarQube (data-flow) is your baseline minimum. Add Snyk Code if your team is on a paid plan for a third, independent perspective.
Layer 3 — DAST on Every Deployable Build: Runtime Checks That Catch What Static Analysis Cannot
Static analysis reads source code. It cannot know that your WebSocket authentication handler is unreachable at runtime because the middleware was never registered in the application bootstrap sequence.
Dynamic Application Security Testing (DAST) runs against a live application. For AI-generated code specifically, runtime testing catches:
- Endpoints that appear authenticated in source but are publicly accessible due to routing misconfiguration
- OAuth redirect URIs that accept wildcards despite the code looking correct
- JWT tokens accepted after expiry because the verification logic is bypassed in certain execution paths
DAST in CI/CD
OWASP ZAP has a maintained GitHub Action that runs a baseline scan against any deployable build:
“`yaml
# .github/workflows/zap-scan.yml
name: ZAP Scan
on:
push:
branches: [main, staging]
jobs:
zap_scan:
runs-on: ubuntu-latest
steps:
- name: ZAP Baseline Scan
uses: zaproxy/action-baseline@v0.11.0
with:
target: ‘https://staging.yourapp.com’
fail_action: true
“`
Run this against your staging environment on every build that touches a deployable artifact. A failed ZAP scan blocks the merge. No exceptions.
Layer 4 — The Manual Auth Review Gate: 10 Points for Any PR That Touches Auth
Some things cannot be automated. A human reviewer should verify the following for every PR that modifies authentication, session management, or access control code.
Authentication:
- [ ] Is auth middleware applied to all transport protocols — including WebSocket and gRPC — not just HTTP routes?
- [ ] Are JWT tokens verified for signature, algorithm (reject `alg: none`), expiry, and issuer?
- [ ] Is 2FA enforcement present on all paths reaching sensitive operations, including account recovery and bypass flows?
Authorization:
- [ ] Is every destructive endpoint (DELETE, PATCH on sensitive resources) protected by an explicit authorization check?
- [ ] Does the access control logic apply consistently across batch and bulk endpoints as well as single-resource endpoints?
- [ ] Are role checks enforced server-side, not just hidden in the UI?
OAuth and Session:
- [ ] Is the OAuth `state` parameter generated, stored, and validated on every authorization flow?
- [ ] Are session tokens invalidated on logout and password change?
- [ ] Is PKCE enforced for public OAuth clients?
General:
- [ ] Has every new dependency introduced in this PR been audited for CVEs and license compatibility?
This gate should be a required status check in your branch protection rules. No PR touching auth merges without a human sign-off on all ten points.
Layer 5 — Toolchain Hygiene: Auditing Claude Code, Copilot, and Codex for CVE-Level Risks
This is the layer nobody talks about — and it’s the one that can expose your entire development environment, not just the code that ships.
Claude Code carries two documented CVEs. CVE-2025-59536 (CVSS 8.7) allows remote code execution by injecting a malicious Hook into `.claude/settings.json`. CVE-2026-21852 allowed API key theft with no user interaction, affecting versions prior to 2.0.65 (Check Point Research, February 2026). GitHub Copilot’s CVE-2025-32711 (CVSS 9.3) demonstrated that a crafted email could silently exfiltrate data from OneDrive, SharePoint, and Teams through a trusted Microsoft domain.
These aren’t theoretical. They’re production CVEs targeting the tools already running in your workflow.
Toolchain hygiene checklist
Claude Code:
- [ ] Pin to the latest patched version (≥ 2.0.65 for CVE-2026-21852)
- [ ] Review `.claude/settings.json` in every project before executing; never run untrusted project configs
- [ ] Restrict Hook execution to an allowlist of approved commands
- [ ] Audit MCP server configurations for unexpected tool registrations
GitHub Copilot:
- [ ] Review Copilot extension permissions; remove extensions with unnecessary data access scopes
- [ ] Confirm your GitHub organization has enabled Copilot audit logging
All agents:
- [ ] Scope AI agent API keys to minimum necessary permissions
- [ ] Rotate any key that appeared in a repository, even briefly
- [ ] Block `.claude/`, `.github/copilot/`, and equivalent config directories from modification in untrusted PRs
OWASP’s Top 10 for Agentic Applications 2026 (ASI01–ASI10) formalizes this threat model. ASI03 (Overprivileged Agents) and ASI02 (Tool Misuse) map directly to the CVEs above. If your organization maintains a formal threat model, mapping CI/CD gates to the ASI categories gives you audit-ready documentation at no extra effort.
Putting It Together: A GitHub Actions Workflow That Enforces All Five Layers
Here’s a composite workflow that automates layers 1, 2, and 3 on every AI-generated PR. Layers 4 and 5 require human process, but this YAML ensures the automated gates all run before any merge is possible:
“`yaml
# .github/workflows/ai-pr-security.yml
name: AI PR Security Gates
on:
pull_request:
branches: [main]
jobs:
secrets-scan:
name: Layer 1 – Secrets and Dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Gitleaks
uses: gitleaks/gitleaks-action@v2
- name: Trivy dependency scan
uses: aquasecurity/trivy-action@master
with:
scan-type: ‘fs’
exit-code: ‘1’
severity: ‘HIGH,CRITICAL’
sast:
name: Layer 2 – SAST Multi-scanner
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Semgrep
uses: semgrep/semgrep-action@v1
with:
config: p/jwt p/owasp-top-ten p/secrets
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
dast:
name: Layer 3 – DAST
runs-on: ubuntu-latest
needs: [secrets-scan, sast]
steps:
- name: ZAP Baseline Scan
uses: zaproxy/action-baseline@v0.11.0
with:
target: ${{ secrets.STAGING_URL }}
fail_action: true
“`
Configure branch protection to require all three jobs to pass, and add the Layer 4 manual reviewer as a required approver on any PR labeled `auth-change`. That combination enforces every automated gate and the human review where it matters most.
Conclusion: Treat AI-Generated PRs Like Unreviewed Code — Because They Are
AI coding agent security vulnerabilities aren’t a reason to abandon these tools. They’re a reason to stop treating AI-generated PRs as equivalent to fully reviewed human code. The DryRun data is unambiguous: 87% of AI-generated PRs contain at least one flaw, and the specific classes repeat predictably — which means they’re catchable with the right tooling in the right place.
A five-layer approach — pre-commit secrets detection, per-PR multi-scanner SAST, runtime DAST, a manual auth review gate, and toolchain hygiene — closes the gap between AI coding velocity and production security without slowing your team down.
Start with Layer 1 and Layer 4 this week. Both are zero-cost, require no new infrastructure, and target the highest-severity issues the research identifies. Drop the GitHub Actions YAML above into your repo when you’re ready to automate the rest.