Vibe Coding Safety: Old Security Habits for AI-Generated Code
Apply proven security habits to AI-generated code. A practical guide for developers using Copilot, Cursor, or ChatGPT to ship safer vibe-coded projects.
The Vibe Coding Security Problem Is Not New
A post on Hacker News with over a thousand points made the rounds this week under the headline "slightly safer vibecoding by adopting old hacker habits." The observation at the core of it is correct: the security principles that mattered in the early 2000s, input validation, least privilege, defense in depth, still apply when your junior developer is a large language model.
This guide translates those principles into a concrete checklist you can paste into your PR template today.
Treat Every AI-Generated Function as Untrusted Input
The most important mindset shift is this: AI-generated code is not your code. It is a probabilistic guess at what code would solve the problem, based on training data that includes insecure code, outdated libraries, and patterns that were acceptable in 2019 but are not acceptable now.
Review it with the same skepticism you would apply to a pull request from someone you have never worked with:
# Before committing AI-generated code, run a dedicated security scan
vouch scan ./src --fail-on high
Never Accept Hardcoded Credentials or Keys
LLMs hallucinate plausible-looking secrets. They fill in example values that look like real credentials because real credentials appeared in their training data. Before you commit any AI-generated file, grep for the patterns:
git diff --staged | grep -Ei '(api_key|secret|password|token)\s*=\s*["\x27][^"\x27]{8,}'
Better yet, run a pre-commit hook that catches this automatically. Tools like detect-secrets integrate in under five minutes.
Verify Every Dependency the Model Adds
LLMs invent package names. They hallucinate version numbers. When a model writes import requests_enhanced or adds fastapi-auth-jwt to your requirements.txt, verify that package exists on PyPI and check its download count and last update date before installing it.
Supply chain attacks via typosquatting and package confusion are the fastest-growing attack vector in developer toolchains right now. A package with 50 downloads and a single contributor that matches the name a model plausibly invented is a red flag.
# Quick check before installing
pip index versions <package-name> 2>&1 | head -5
curl -s https://pypi.org/pypi/<package-name>/json | python3 -c \
"import sys,json; d=json.load(sys.stdin); print(d['info']['downloads'])"
Enforce Explicit Output Encoding
LLMs write templates that concatenate user data into HTML without encoding, and they write SQL queries with f-strings. Both patterns were the source of the web's most exploited vulnerability classes in the 2000s and they are back.
# Dangerous: LLM-generated template rendering
return f"<div>Hello {username}</div>"
# Safe: explicit encoding
from markupsafe import escape
return f"<div>Hello {escape(username)}</div>"
For database queries, the rule is identical to what it was in 2005: never interpolate user data into SQL. Use parameterized queries, always.
Add Dependency Scanning to Your CI Pipeline
The old habit of pinning dependencies and checking them against vulnerability databases is more important now than ever. AI assistants will suggest npm install commands without specifying versions, and they will not tell you that the version they picked has a known CVE.
# In your GitHub Actions workflow
- name: Audit dependencies
run: |
npm audit --audit-level=high
pip-audit --requirement requirements.txt
Running this on every pull request means a model-suggested dependency with a known vulnerability fails the build before it reaches production.
Key Takeaways
- AI-generated code should be reviewed with the same skepticism as a pull request from an unknown contributor, because the model has no stake in the security of your production environment.
- The vulnerability patterns LLMs introduce most often, hardcoded secrets, missing output encoding, SQL injection via f-strings, are the same ones developers were warned about decades ago.
- A pre-commit hook for secret detection, a dependency audit in CI, and an automated security scan on pull requests close most of the gap without slowing down the development workflow.