"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
- Why "it works" isn't enough
- The 12-Item Vibe Coding Security Checklist
- Auth and Authorization: The Silent Absence of RLS
- Audit step
- Secret and Env Leakage: Commits, Client Bundles, Logs
- Audit step
- The Dependency Chain: Hallucinated Packages and Version Pinning
- Audit step
- The Agent's Own Permissions: Sandbox, Allowlist, Working-Directory Lock
- Audit step
- Real Incidents and a Recurring Pattern
- Audit step
- Automated Gates to Wire into CI
- Audit step — minimal CI gate
- Embedding the Checklist into the Code Review Process
- Audit step
- FAQ
- Is code written with vibe coding secure?
- What are the most common security flaws in AI-written code?
- What security checks should be run before pushing AI-generated code to production?
- How do I prevent an AI coding agent from leaking secrets?
- Conclusion
- Sources
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.
1-- Correct pattern: table + RLS + policy must arrive together2CREATE 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 profiles5 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
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 key5grep -r "service_role\|SUPABASE_SERVICE" .next/static/ 2>/dev/nullIf 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
1# Verify every package in package.json actually exists2cat package.json | jq -r '.dependencies | keys[]' | while read pkg; do3 npm view "$pkg" version >/dev/null 2>&1 || echo "WARNING: $pkg not found"4doneUsing 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
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
1# .github/workflows/security-gate.yml2name: security-gate3on: [pull_request]4jobs:5 security:6 runs-on: ubuntu-latest7 steps:8 - uses: actions/checkout@v69 with:10 fetch-depth: 011 - name: RLS check12 run: |13 missing=$(grep -L "ENABLE ROW LEVEL SECURITY" prisma/migrations/*/migration.sql || true)14 if [ -n "$missing" ]; then15 echo "Migration missing RLS found:"16 echo "$missing"17 exit 118 fi19 - name: Secret scan20 uses: gitleaks/gitleaks-action@v321 env:22 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}23 - name: Dependency audit24 run: npm audit --audit-level=highThese 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
- Vibe Coding Security — Legit Security ASPM Knowledge Base — a general framework for recurring vulnerability classes in vibe coding (RCE/eval, XSS, SQLi, secrets exposure)
- 2025 GenAI Code Security Report — Veracode — measurement showing 45% of code samples from more than 100 language models failed security tests
- We Have a Package for You! (Slopsquatting) — arXiv:2406.10279 — measurement of hallucinated package rates across 576,000 samples (21.7% open-source, 5.2% commercial)
- The Range Shrinks, the Threat Remains — arXiv:2605.17062 — follow-up study showing the hallucinated package rate narrowed to 4.62–6.10% in a 2026 frontier-model cohort
- CVE-2025-48757 — mattpalmer.io — official disclosure of the critical vulnerability arising from insufficient RLS policies in Lovable/Supabase projects
- Statement on CVE-2025-48757 — mattpalmer.io — research note documenting that the scan found insufficient RLS in 170 of 1,645 projects (10.3%)
- Exposed Moltbook Database — Wiz Blog — analysis of the incident where a client-side embedded Supabase key combined with missing RLS
- Tea App's Data Breach Gets Much Worse — TechCrunch — coverage of the breach exposing more than 1.1 million private direct messages
- CWE-798: Use of Hard-coded Credentials — MITRE — official definition of the hardcoded credential vulnerability class
- CWE-863: Incorrect Authorization — MITRE — official definition of the incorrect authorization vulnerability class
- Claude Code Permissions — code.claude.com — deny/allow precedence in the agent permission system and gitignore-pattern syntax for Read/Edit rules
- Claude Code Sandboxing — code.claude.com — default write-access scope of sandboxed bash commands
- Codex Security, now in research preview — OpenAI — primary source announcing 792 critical and 10,561 high-severity findings across a scan of more than 1.2 million commits
Tags
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.

