Vibe Coding Security: The Essential Guide for AI-Assisted Developers
Vibe coding — building software by rapidly prompting AI assistants — has democratized software development. You don't need a CS degree to ship a SaaS anymore. But there's a catch: speed without security is technical debt with interest.
This guide covers everything you need to know about vibe coding security: the risks, the common vulnerabilities, and how to ship confidently.
What Makes AI-Generated Code Insecure?
AI coding assistants are trained on public code — which includes a lot of insecure code. They optimize for "code that looks right" not "code that's secure." Here's what goes wrong:
1. AI Doesn't Understand Context
When you ask AI to "create a login endpoint," it generates code that works — but it might not know:
- You're handling sensitive user data
- This endpoint needs rate limiting
- Passwords should be hashed with bcrypt, not stored plainly
- Sessions need secure cookies
2. Training Data Includes Vulnerable Patterns
Public repositories contain SQL injection, XSS vulnerabilities, and hardcoded secrets. AI learns these patterns and reproduces them.
3. No Security Mental Model
AI doesn't have a threat model. It doesn't think: "What if an attacker tries to bypass this?" It thinks: "What code makes this feature work?"
Top 7 Security Vulnerabilities in Vibe-Coded Apps
1. SQL Injection
The Problem: AI generates queries using string interpolation.
// ❌ AI-generated vulnerable code
const user = await db.query(
`SELECT * FROM users WHERE id = '${req.params.id}'`
);
// ✅ Safe alternative
const user = await db.query(
'SELECT * FROM users WHERE id = $1',
[req.params.id]
);
How to Catch It: Search your codebase for:
- Template literals in SQL queries
- String concatenation with user input
- Any query that includes
${req.or${request.
2. Cross-Site Scripting (XSS)
The Problem: AI renders user input without escaping.
// ❌ Vulnerable React component
function Comment({ text }) {
return <div dangerouslySetInnerHTML={{ __html: text }} />;
}
// ✅ Safe alternative
function Comment({ text }) {
return <div>{text}</div>; // React escapes by default
}
3. Hardcoded Secrets
The Problem: AI includes placeholder API keys that never get rotated.
# ❌ Never do this
STRIPE_KEY = "sk_live_abc123..."
DATABASE_URL = "postgresql://user:password@localhost/db"
# ✅ Use environment variables
STRIPE_KEY = os.environ.get("STRIPE_KEY")
DATABASE_URL = os.environ.get("DATABASE_URL")
Scan for: sk_live_, sk_test_, AKIA, password = ", api_key = "
4. Missing Authentication
The Problem: AI creates endpoints without auth checks.
// ❌ No authentication
app.delete('/api/users/:id', async (req, res) => {
await User.delete(req.params.id);
res.json({ deleted: true });
});
// ✅ With authentication
app.delete('/api/users/:id', authMiddleware, async (req, res) => {
if (!req.user.isAdmin) return res.status(403).json({ error: 'Forbidden' });
await User.delete(req.params.id);
res.json({ deleted: true });
});
5. Insecure Direct Object References (IDOR)
The Problem: Users can access other users' data by changing IDs.
// ❌ Vulnerable
app.get('/api/invoices/:id', async (req, res) => {
const invoice = await Invoice.findById(req.params.id);
res.json(invoice); // Any user can access any invoice!
});
// ✅ Check ownership
app.get('/api/invoices/:id', authMiddleware, async (req, res) => {
const invoice = await Invoice.findOne({
_id: req.params.id,
userId: req.user.id // Only return user's own invoices
});
if (!invoice) return res.status(404).json({ error: 'Not found' });
res.json(invoice);
});
6. Dangerous Function Calls
The Problem: AI suggests eval(), exec(), and other dangerous functions.
// ❌ Never use eval with user input
const result = eval(req.body.expression);
// ❌ Command injection risk
const output = exec(`ls ${req.query.directory}`);
// ✅ Safer alternatives
// Use a math library instead of eval
// Use parameterized child_process with explicit arguments
7. Missing Input Validation
The Problem: AI trusts user input without validation.
// ❌ No validation
app.post('/api/users', async (req, res) => {
await User.create(req.body); // What if req.body has admin: true?
});
// ✅ Validate with a schema
const userSchema = z.object({
email: z.string().email(),
name: z.string().min(1).max(100),
// admin field not allowed
});
app.post('/api/users', async (req, res) => {
const validated = userSchema.parse(req.body);
await User.create(validated);
});
Your Vibe Coding Security Checklist
Before deploying any AI-generated code, run through this checklist:
Code Review
- [ ] No string interpolation in SQL queries
- [ ] No
eval(),Function(), orexec()with user input - [ ] All sensitive endpoints have authentication
- [ ] User input is validated before use
- [ ] No hardcoded secrets (API keys, passwords, tokens)
- [ ] Error messages don't leak sensitive information
Dependencies
- [ ] Run
npm auditorpip audit - [ ] Update packages with known CVEs
- [ ] Remove unused dependencies
Configuration
- [ ] Secrets stored in environment variables
- [ ]
.envfiles in.gitignore - [ ] CORS configured correctly
- [ ] HTTPS enforced in production
Testing
- [ ] Test authentication bypass attempts
- [ ] Test SQL injection on all input fields
- [ ] Test XSS on all text rendering
- [ ] Verify authorization on sensitive endpoints
Tools for Vibe Coding Security
1. VCX — AI Codebase Auditor
VCX scans your entire codebase for:
- Security vulnerabilities (SQL injection, XSS, auth issues)
- Hardcoded secrets
- Dangerous patterns
- Architecture issues
Best for: Comprehensive pre-launch audit
2. ESLint + Security Plugins
npm install eslint-plugin-security
Best for: Catching issues during development
3. npm audit / pip audit
npm audit
pip audit
Best for: Dependency vulnerability scanning
4. Gitleaks
gitleaks detect --source . --verbose
Best for: Finding leaked secrets in git history
Building a Secure Vibe Coding Workflow
Before You Code
- Set up environment variable management (dotenv, 1Password)
- Configure ESLint with security rules
- Plan your auth strategy upfront
During Development
- Review every AI-generated function before accepting it
- Ask AI: "Are there security concerns with this approach?"
- Run local security scans frequently
Before Deployment
- Run a full VCX audit
- Fix all CRITICAL and HIGH findings
- Test authentication and authorization manually
- Have a human review critical paths
The Bottom Line
Vibe coding isn't insecure by default — but it requires intentional security practices. AI is an incredible productivity tool, but it's not a security expert.
Your workflow should be:
- Prompt AI to generate code
- Review the code with security in mind
- Scan with deterministic tools (not AI guessers)
- Test critical paths manually
- Ship with confidence
Don't let speed become your biggest vulnerability.
Ready to audit your AI-generated codebase?
Scan your repo free at vibecode-xray.com
Related Reading: