All Articles
CategoryVibe Coding
Reading Time
13 min read
Published
2026-09-04
Word Count
3,308words

Grab a coffee — this one is a deep dive!

Vibe Coding Security Checklist: 12 Critical Audits

Summary

45% of AI-generated code samples failed security tests. Here are 12 concrete, auditable checks — grounded in real CVEs and production incidents — to run before you ship code an agent wrote for you.

  • 45% of AI-generated code samples failed security tests and introduced an OWASP Top 10 vulnerability (Veracode 2025 GenAI Code Security Report) — the "it works" test doesn't catch broken authorization or leaked secrets.
  • RLS/row-level security stays off by default on tables created via migration; a CVE-2025-48757 scan found 170 of 1,645 Lovable projects exposed this way (NVD: CVSS 9.3).
  • Dependency hallucination (slopsquatting) averages at least 21.7% on open-source models — every package needs registry verification.
  • The agent's own file/bash permissions are part of the audit surface too: the deny list must cover .env and secrets/ paths, and the sandbox must not escape the working directory.
Vibe Coding Security Checklist: 12 Critical Audits

"It works, so it's done" is the most dangerous sentence in vibe coding. Without a vibe coding security checklist, code an AI agent writes for you can run flawlessly on screen while shipping a table with a missing RLS policy, an API key baked into the client bundle, or a package that doesn't even exist to production. This piece walks through 12 concrete items you need to audit before shipping code you never typed a single line of by hand — grounded in real CVEs, academic measurements, and production incidents.

💡 Pro Tip: Think of this checklist as a "production configuration review," not a "code review" — in vibe coding the real risk isn't a logic bug, it's an authorization left open by default or a leaked secret.

Table of Contents

Why the Gap Forms Differently in Vibe Coding

In traditional code review, the developer writes every line, then someone else reads it. In vibe coding this order flips: the developer's role shifts from "implementer" to "reviewer," and line-by-line comprehension drops. The result is a recurring, predictable vulnerability class — RCE/eval usage, encoding-bypassing XSS, string-concatenated SQL, memory corruption, and leaked secrets (Legit Security, ASPM knowledge base).

This pattern has been measured: Veracode's 2025 GenAI Code Security Report found that 45% of code samples from more than 100 large language models failed security tests and introduced an OWASP Top 10 vulnerability. That figure doesn't mean "AI writes bad code" — it means "if you don't read AI-generated code with as much suspicion as you'd read a human's, you'll miss the holes." That's where the checklist starts: read every output like an intern's first PR.

Why "it works" isn't enough

An agent can hand you a working login form, a working API endpoint — but the "it works" test doesn't test authorization, input validation, or secret management. These three areas form the backbone of the 12-item list below.

The 12-Item Vibe Coding Security Checklist

The list below summarizes the concrete, auditable checks explained one by one in the sections that follow. Each item is written so it can be answered "yes/no" — don't accept a vague answer like "looks generally secure."

#
Checklist Item
Audit Method
1
Is RLS/row-level policy active on every table?
Search migration files for ENABLE ROW LEVEL SECURITY
2
Is auth middleware mandatory on every API route?
Match the route list against the auth middleware list
3
Is there hardcoded credential in the code?
grep -rnE "api_key|secret|password" --include="*.ts"
4
Has .env leaked in past commits?
git log -p -- .env + check .gitignore
5
Is an admin/service-role key embedded in the client bundle?
Search the build output for the service_role string
6
Are SQL queries parameterized?
Search for queries built with string concatenation
7
Does every dependency actually exist?
npm view <package> / pip index versions <package>
8
Are versions exact-pinned?
Check for a full version number instead of ^/~
9
Is the agent's file access limited by an allowlist?
Read deny/allow globs in the permission config
10
Can the agent escape the working directory?
Test the sandbox setting and absolute-path access
11
Are secrets/PII written to log files?
Search log output for token/email patterns
12
Does CI have SAST + secret-scan + dep-audit?
Verify the relevant steps in the pipeline YAML

Auth and Authorization: The Silent Absence of RLS

The most common and most expensive error class in vibe coding isn't badly written code — it's the authorization layer that never gets written at all. On backend-as-a-service platforms like Supabase, when a table is created via a SQL migration or an AI tool, Row Level Security stays OFF by default — it only turns on automatically for tables created manually through the Table Editor UI. As long as an agent produces a migration file for "create a user profile table," this off-by-default state persists.

CVE-2025-48757, published in May 2025, documents exactly this pattern: a scan by security researcher Matt Palmer found missing or insufficient RLS policies in 170 of 1,645 Lovable projects examined (roughly 10.3%); the NVD record assigned the vulnerability a CVSS score of 9.3 (critical) — the same record also carries a disputed tag reflecting Lovable's objection. This is a textbook example of "incorrect authorization" (CWE-863) — MITRE's CWE-863 definition covers the case where a product does perform an authorization check but doesn't perform it correctly.

Audit step

Search every migration file for ENABLE ROW LEVEL SECURITY and a corresponding CREATE POLICY line; if either is missing, the table is open to everyone by default.

sql
1-- Correct pattern: table + RLS + policy must arrive together
2CREATE TABLE profiles (id uuid PRIMARY KEY, user_id uuid REFERENCES auth.users);
3ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
4CREATE POLICY "kullanici_kendi_verisi" ON profiles
5 FOR SELECT USING (auth.uid() = user_id);

Secret and Env Leakage: Commits, Client Bundles, Logs

Legit Security's ASPM knowledge base identifies three recurring leak patterns in vibe coding output: hardcoded credentials embedded in source files, API keys in .env files committed to the repo, and tokens logged during debugging. The first two fall under CWE-798 (Use of Hard-coded Credentials) — per MITRE's definition, this vulnerability class means software contains a hard-to-change credential embedded directly in its source code or configuration file.

The Moltbook incident, which surfaced in February 2026, is a concrete instance of this pattern: according to Wiz researchers, a Supabase API key with no RLS policy sat directly inside a production JavaScript file, and it was found simply by inspecting that file. The exposed data covered tens of thousands of users' email addresses (source: wiz.io/blog). The key itself wasn't "secret" — it lived inside a publicly accessible JavaScript bundle.

Audit step

bash
1# Scan past commits for .env leaks ("**/" misses a root-level .env, root patterns are required)
2git log --all --full-history -- ".env" ".env.*" "**/.env" "**/.env.*"
3 
4# Search the build output for traces of a service-role/admin key
5grep -r "service_role\|SUPABASE_SERVICE" .next/static/ 2>/dev/null

If a key shows up in the client bundle, it's already leaked — rotation is the only fix; "nobody will look" is not a valid assumption.

The Dependency Chain: Hallucinated Packages and Version Pinning

AI agents "hallucinating" non-existent package names when suggesting dependencies (a risk termed slopsquatting) is a problem that has been measured academically. A study by Spracklen et al. across 576,000 code samples (arXiv:2406.10279) found an average hallucination rate of at least 5.2% for commercial models and at least 21.7% for open-source models. The same study also found that 8.7% of hallucinated Python packages were actually valid JavaScript packages.

A 2026 follow-up study (arXiv:2605.17062) found that range narrowed from 5.2–21.7% to 4.62–6.10% — an improvement, but the risk wasn't eliminated. An attacker can mount a supply-chain attack by actually publishing a frequently-hallucinated package name (an AI-specific version of typosquatting).

Audit step

bash
1# Verify every package in package.json actually exists
2cat package.json | jq -r '.dependencies | keys[]' | while read pkg; do
3 npm view "$pkg" version >/dev/null 2>&1 || echo "WARNING: $pkg not found"
4done

Using an exact pin (1.2.3) instead of a version range (^1.2.3) also prevents the agent from jumping to a different (and unverified) minor version on the next run — that's the second pillar of supply-chain auditing.

The Agent's Own Permissions: Sandbox, Allowlist, Working-Directory Lock

The first eight items looked at the code the agent produces; items 9 and 10 look at the agent itself, and 11 and 12 look at runtime and the CI pipeline. The agent's filesystem, network, and command-execution permissions are a surface just as auditable as "generated code." Per Claude Code's official documentation, Read and Edit permission rules use gitignore-style patterns, and deny always takes precedence over allow (code.claude.com/docs/en/permissions); sandboxed bash commands can write, by default, to the working directory, the session's temp directory, and any directories you've explicitly added (code.claude.com/docs/en/sandboxing).

These three rules translate into a checklist of their own: does the agent's configuration have a deny list, are sensitive paths like .env/secrets/ explicitly denied, and does bash execution grant write access outside the working directory (/etc, ~/.ssh)?

Audit step

json
1{
2 "permissions": {
3 "deny": ["Read(./.env)", "Read(./secrets/**)", "Bash(rm -rf *)"],
4 "allow": ["Bash(npm test)", "Bash(git diff)"]
5 }
6}

Separately, Cursor announced "self-hosted machines" — the agent's tool calls can now run on the customer's own infrastructure (AWS Lambda, Cloudflare, Daytona, Modal, Vercel, E2B), so code and secrets never leave for a third-party server (cursor.com/changelog/self-hosted-machines). This is the infrastructure-level counterpart of auditing "the agent's permissions."

Real Incidents and a Recurring Pattern

To make the theory concrete, consider two production incidents. In July 2025, the Tea app data breach exposed more than 1.1 million private direct messages (TechCrunch) — cited here purely for scale; the source doesn't document a link to the app being AI-generated. In the February 2026 Moltbook incident above, a client-side Supabase key combined with a missing RLS policy exposed tens of thousands of users' email addresses (Wiz).

Placing Moltbook and CVE-2025-48757 side by side reveals a common pattern: in neither case did anyone write a custom exploit or use a zero-day — they simply noticed that a publicly accessible application skipped a basic authorization check. This is exactly why a vibe coding security checklist needs to exist: "basic misconfiguration" is the cheapest find for an attacker, because finding it requires no special knowledge.

Audit step

Before shipping, ask: "If nobody ever tested this feature, what's the easiest way it could be abused?" The answer is usually "by hitting an unauthorized endpoint" or "by using a key visible on the client" — both are already covered by the first five of the 12 items in this piece.

Automated Gates to Wire into CI

Checking a 12-item list by hand on every PR isn't sustainable — which is why the last item is about automating the rest of the list. Three layers are recommended: SAST (static code analysis, which catches encoding/SQL/eval patterns), secret-scan (which blocks keys entering commits at the PR stage), and dependency-audit (which flags hallucinated or known-vulnerable packages).

According to OpenAI, the Codex Security tool announced in March 2026 aims to produce sandbox-verified, prioritized findings instead of noisy SAST output; in the 30 days before the announcement it scanned more than 1.2 million commits across external repositories and identified 792 critical and 10,561 high-severity findings. Add a project-specific gate too: wire the RLS/auth check into CI against the migration diff — the practical fix for CVE-2025-48757 is automatically verifying every migration contains an ENABLE ROW LEVEL SECURITY line.

Audit step — minimal CI gate

yaml
1# .github/workflows/security-gate.yml
2name: security-gate
3on: [pull_request]
4jobs:
5 security:
6 runs-on: ubuntu-latest
7 steps:
8 - uses: actions/checkout@v6
9 with:
10 fetch-depth: 0
11 - name: RLS check
12 run: |
13 missing=$(grep -L "ENABLE ROW LEVEL SECURITY" prisma/migrations/*/migration.sql || true)
14 if [ -n "$missing" ]; then
15 echo "Migration missing RLS found:"
16 echo "$missing"
17 exit 1
18 fi
19 - name: Secret scan
20 uses: gitleaks/gitleaks-action@v3
21 env:
22 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23 - name: Dependency audit
24 run: npm audit --audit-level=high

These three steps automatically audit three of the 12 items (1, 3, and 4) on every PR; the remaining nine (client bundle scanning, the logical correctness of RLS policy, the agent's permission configuration, etc.) require a separate step or manual review.

Embedding the Checklist into the Code Review Process

Rather than squeezing the 12-item list into one "security audit" step, it's more sustainable to split it into three phases: before the agent starts coding (permission configuration, allowlist), right after it produces code (auth/RLS/secret scanning, within its own session), and before the PR merges (CI gates). This split lets each phase take on its own natural responsibility, instead of expecting one person or tool to catch everything.

In practice this means: when setting up a new project, write the agent's permission file (.claude/settings.json or its equivalent) in the first commit, and add .env and secrets/ paths to the deny list. After the agent produces a feature, append the sentence "now audit this code yourself for CWE-863 and CWE-798" to the end of the same prompt — this is the daily-workflow version of the second-pass technique described in the Golden Tip section. By the time a PR opens, the three automated CI gates (SAST, secret-scan, dependency-audit) have already run; human review can then focus purely on "is the logic correct," not "did a secret leak."

Audit step

As the team grows, turn these three phases into a template PR description: "Was the permission configuration updated? Was the agent's second-pass audit done? Are the CI gates green?" — three boxes, three phases, status at a glance.

GOLDEN TIP

The most valuable insight in this article

This tip holds the article's most important takeaway.

Easter Egg

You found a hidden gem!

There's a hidden detail in this section. Want to uncover it?

Reader Reward

We've distilled the 12 items in this article into a single-page, plain checklist you can paste straight into a PR description. Check off each line to run a fast final pass before shipping.

FAQ

Is code written with vibe coding secure?

Not automatically. According to Veracode's 2025 GenAI Code Security Report, 45% of AI-generated code samples failed security tests and introduced an OWASP Top 10 vulnerability. This doesn't mean vibe coding is inherently insecure — it means, like any code produced without human review, it carries risk if shipped unaudited. Applying the 12-item checklist in this piece measurably reduces that risk.

What are the most common security flaws in AI-written code?

The recurring pattern is incorrect authorization (CWE-863, especially RLS staying off by default), hardcoded credentials (CWE-798), and unparameterized SQL queries (CWE-89). These three vulnerability classes show up prominently both in Legit Security's observations and in documented incidents like CVE-2025-48757.

What security checks should be run before pushing AI-generated code to production?

The full 12-item checklist in this piece: RLS/auth checks, secret scanning, dependency verification, and reviewing the agent's own permission configuration. Running SAST + secret-scan + dependency-audit steps automatically in CI makes most of these checks repeatable on every PR.

How do I prevent an AI coding agent from leaking secrets?

You need three layers: add .env to .gitignore and scan past commits, set up an automated step to search the build output for a service-role/admin key, and explicitly add .env/secrets/ paths to the deny list in the agent's configuration — Claude Code's permission system supports this kind of glob-based denial (code.claude.com/docs/en/permissions).

Conclusion

The speed vibe coding brings doesn't eliminate the responsibility to audit — it just moves where that responsibility gets applied: from line-by-line code review to configuration and authorization auditing. The 12-item list in this piece is a reminder, as CVE-2025-48757 and the Moltbook incident show, that the most expensive mistakes usually come from the simplest missing checks.

If you want to go deeper, iOS Security Best Practices covers general mobile security principles, iOS Keychain and Security covers secret management at the platform level, and iOS Network Security Advanced covers network-layer hardening. To see agent-side risk in a broader context, check out 10 Misconceptions About AI Coding and, for tool selection, the GitHub Copilot vs Claude Code vs Cursor comparison.

Sources

Tags

#vibe coding#security#AI agents#RLS#secret management#CI/CD#Claude Code#Supabase
Muhittin Çamdalı

Muhittin Çamdalı

Lead Mobile Engineer

Lead Mobile Engineer with 12+ years of experience. Expert in iOS, Android and cross-platform architectures with Swift, SwiftUI, Kotlin and Flutter. I build performant, user-friendly mobile apps.

iOS Development News

Weekly Swift tips, SwiftUI tricks and iOS best practices. No spam, only valuable content.

We respect your privacy. You can unsubscribe at any time.

Share