Vibe Coding Safety

What AI-generated code produces at speed, what breaks when you skip review, and how BrassCoders provides the gate the model never was.

Andrej Karpathy named the practice in February 2025: use AI as the primary author, accept suggestions wholesale, barely read the output. Vibe coding. The practice spread because it works — at least on the first run. Veracode's 2026 State of Software Security report found 45% of AI-generated code samples introduced at least one OWASP Top 10 vulnerability on first generation. The model produces confident-looking code. It does not produce warnings.

BrassCoders is the deterministic gate that runs between the AI's output and your commit. This page is the canonical reference for the vibe coding security question: what breaks, why, and what stops it.

The Velocity Risk

BrassCoders published the N=15 AI-code-findings corpus — 15 Python files generated from neutral prompts, scanned without asking the model to review for security. Nine of fifteen carried a real issue. The model issued zero proactive security warnings during generation on any of them.

That gap — confident generation, silent on security — is the velocity risk. Vibe coding removes the review step that would have caught the findings. The velocity risk post documents the evidence in detail, including Perry et al.'s CCS 2023 finding that AI-assisted development correlates with higher rates of insecure code. The vibe coding safety net post is the cornerstone: what BrassCoders catches, how it fits into the vibe coding workflow.

What AI-Generated Code Produces

BrassCoders's published corpus and scanner rule coverage point to five recurring security patterns in AI-generated Python code. Each one is structural — the scanner catches it without reading the application logic.

Pattern Why AI produces it BrassCoders catch
SQL injection via f-string f-string query satisfies the prompt; parameterized form is more complex Bandit B608
Hardcoded credentials Model fills credential fields with plausible-looking values detect-secrets + 7 custom patterns
shell=True in subprocess Syntactically simpler; satisfies the "run this command" prompt Bandit B602/B603
Missing CSRF on Flask routes Flask has no built-in CSRF; Flask-WTF omitted unless prompted Bandit + custom rule
Debug mode in production config Quickest working Flask example uses debug=True Bandit B201/B202

Flask: The Framework That Trusts You Too Much

BrassCoders's scanner coverage for Flask catches four patterns AI assistants produce on nearly every Flask scaffold: missing CSRF, debug mode enabled, hardcoded secret_key, and SQL injection in route handlers. Flask has no built-in CSRF protection — unlike Django, it requires an extension (Flask-WTF). AI assistants omit it because nothing in the base Flask API signals it's missing. The route works. The vulnerability ships.

The Flask security post walks through all four patterns with working examples and the BrassCoders commands that surface them. It completes the framework trilogy alongside Django and FastAPI.

Your AI Doesn't Know Your Secrets Policy

BrassCoders detects 20+ secret formats because AI coding assistants have no access to your organization's secrets management policy. They generate code that works — which means completing credential fields with whatever looks plausible. The N=15 corpus found hardcoded credentials in two of fifteen files. Vibe coding removes the review step that would have caught them manually.

The secrets policy post covers the organizational gap — why prompting alone doesn't solve it, what BrassCoders catches, and the workflow for rotating findings before they ship. For the credential detection mechanics, see the hardcoded credentials post.

Path Traversal: The File Operation Bug AI Ships Without Prompting

BrassCoders flags path traversal patterns when user-controlled input flows into file path construction without sanitization. os.path.join(upload_dir, user_filename) is syntactically correct — and dangerous when user_filename is ../../../etc/passwd. AI assistants generate file operation code that satisfies the "save this file" prompt without checking whether user input can escape the intended directory.

The path traversal post covers the pattern, the scanner's scope, and what the AI triage layer handles that deterministic rules can't.

Scaling to a Team

BrassCoders's determinism — same code produces the same findings, every run, every developer — is the property that makes it a team-level gate rather than a per-developer preference. Ten developers using different AI assistants with different prompts produce ten different vulnerability surfaces. One scanner running the same rules covers all of them consistently.

The team consistency post covers the scaling argument. The GitHub Actions post and GitLab CI post cover the CI integration that makes the gate automatic.

The Practical Setup

BrassCoders wires into a vibe coding workflow in three commands:

# Install
pip install brasscoders

# Scan before opening a PR (offline — zero bytes leave the machine)
brasscoders scan /path/to/your/project

# Add the pre-commit hook so it runs automatically
brasscoders install-hook

The pre-commit hook post covers the full setup. The triage post covers what to do with findings when an AI PR is large.

Why the Model Doesn't Fix This

Better AI models don't close the security gap — they may widen it. Why Better AI Models Make Bugs Harder to Catch documents the mechanism: more capable models produce more plausible-looking code, which is harder to review quickly and less likely to trigger the developer's caution reflex. The patterns that BrassCoders catches don't change; the confidence level of the code around them does.

The division of labor is load-bearing: BrassCoders is the dumb-but-honest pattern reporter. Claude Code (or Cursor, Continue, Aider) is the smart triage layer that reads the .brass/ai_instructions.yaml findings file and applies context. The model judges what looks right; BrassCoders catches what is deterministically wrong.

All Vibe Coding Safety Posts

Frequently Asked Questions

Is vibe coding safe for production?

Vibe coding produces code with the same vulnerability patterns as any AI-generated code — it just removes the review step between generation and commit. BrassCoders's published N=15 AI-code-findings corpus found real security issues in 9 of 15 AI-generated Python files, with zero generation-time warnings from the model. Production safety depends on what runs between the AI output and the deploy.

What does vibe coding actually mean?

Andrej Karpathy coined the term in February 2025 to describe using AI as the primary code author — accepting suggestions wholesale, guiding by natural language, barely reading the output. The developer vibe-checks the result rather than reviewing it line by line. The practice has spread from solo side projects into production codebases.

Does vibe coding produce more security vulnerabilities than human-written code?

The evidence says yes. Perry et al. (CCS 2023) found participants using AI assistants wrote significantly more insecure code than those without — higher rates of injection, authorization, and cryptographic vulnerabilities. Veracode's 2026 State of Software Security report found 45% of AI-generated code samples introduced at least one OWASP Top 10 vulnerability. Vibe coding, which compresses the review step further, moves the risk in the same direction.

Does BrassCoders slow down vibe coding?

BrassCoders runs offline in seconds and produces a structured findings file. The pre-commit hook integration makes it automatic — the scan runs when you commit, not while you're writing. The fast path is: brasscoders scan → findings file written → open Claude Code for triage. Velocity doesn't change; the gap where bugs ship does.

What Flask security bugs do AI assistants ship?

Four patterns appear consistently in AI-generated Flask code: missing CSRF protection on form routes (Flask has no built-in CSRF; Flask-WTF is omitted unless specifically prompted), debug mode left enabled in production configuration, hardcoded secret_key values, and SQL injection via f-string query construction in route handlers. BrassCoders catches all four without reading the application logic.

My team uses different AI assistants. Does that mean different security posture?

Different AI assistants produce different code, but BrassCoders scans the output, not the model. SQL injection via f-string formatting looks the same whether Claude Code or GitHub Copilot wrote it — BrassCoders flags it either way. The deterministic scan is what makes the team-level gate consistent regardless of individual AI tool choices.

How do I add security to a vibe coding workflow without slowing the team down?

Three steps: install BrassCoders (`pip install brasscoders`), add the pre-commit hook (runs automatically on each commit), add the CI gate (runs on every PR before merge). The scan is offline by default — zero bytes leave the machine — and runs in seconds. The team inherits the security baseline without changing their day-to-day workflow.