
9/7/2025 • 14 min read
Vibe Coding Is Great - Until It Isn't: Why Security Matters
Last updated: September 7, 2025
Vibe coding makes building faster than ever—but it comes with risks. Learn why security can't be an afterthought, and how Rafter keeps builders safe.
The Rise of Vibe Coding
Vibe coding has revolutionized how we build software. With AI-powered tools, rapid prototyping, and intuitive frameworks, developers can now ship features faster than ever before. The excitement of seeing ideas come to life in real-time is unmatched.
But speed comes with a cost.
Some experienced developers, however, have been around the block and know the risks of vibe coding. They know that security is a critical part of the development process.
According to the 2025 Developer Survey, by Stack Overflow:
Privacy, pricing and better alternatives are top reasons developers turn their back on a technology.
The Security Blind Spot
When we're in the zone, focused on shipping features and iterating quickly, security often becomes an afterthought. We tell ourselves:
- "I'll add authentication, role-based access, input validation, and RLS later"
- "Security can wait until we have users"
- "This is just a prototype anyway"
The problem? Security vulnerabilities don't wait for convenient timing. Hackers find them. Especially when we build in public, launch on Product Hunt, and post our code, public and open source, on GitHub.
The Measurable Risks of AI-Generated Code
It's tempting to think that AI code assistants only introduce minor bugs or stylistic issues. But research shows the risks are both systemic and severe.
Worse, manual review is often not enough. Testing the functionality of the code doesn't have anything to do with security; in fact, it can encourage the creation of insecure code. When vibe-coding we tell [insert your favorite AI coding assistant here] to "just make it work" without understanding the security implications.
The range of error rates in AI-generated code is staggering. Studies consistently show that AI assistants don't just produce quirky bugs—they generate insecure, vulnerable, or outright incorrect code at alarming rates:
- 5-20% error rate in generated code (Cotroneo et al., August 2025)
- 24-29% error rate in Python and Java generated code (Feng et al., February 2025)
- 40% of Copilot suggestions insecure in security-sensitive contexts (Pearce et al., February 2021)
- 45% of AI-generated code contained vulnerabilities (Veracode, July 2025)
- 49% of outputs vulnerable or incorrect (BaxBench, February 2025)
- 84% of open-source projects include vulnerable dependencies, convoluting training data (Synopsys OSSRA 2025)
The pressure to keep up makes it even worse: A Checkmarx (2025) survey revealed that 81% of companies knowingly ship vulnerable code, in part due to the pressure to move fast with AI-accelerated workflows.
And despite these risks, adoption is skyrocketing: 84-92% of developers now use AI coding tools (GitHub, 2024, Stack Overflow, 2025).
The numbers make it clear: the risks of vibe coding aren't theoretical. They're quantifiable, repeatable, and already impacting real projects. Security isn't just a "nice-to-have"—it's the difference between innovation and catastrophe.
Why Security Can't Wait
1. Technical Debt Compounds
Every security shortcut you take today becomes harder to fix tomorrow. What starts as a "temporary" solution often becomes permanent technical debt.
2. Users Arrive Faster Than Expected
When your app gains traction, those security gaps become attack vectors. Fixing them under pressure is expensive and risky.
3. Compliance Requirements
Many industries have strict security requirements. Retrofitting security into existing code is much harder than building it in from the start.
4. Reputation Damage
A single security breach can destroy trust that took years to build. Users expect their data to be safe. They will abandon ship at the first sign of a breach.
Common Vibe Coding Security Pitfalls
When you're in the flow, these security issues are easy to miss. But each one can become a critical vulnerability that compromises your entire application. Let's break down the most common pitfalls, why they're dangerous, and exactly how to fix them.
Throughout this section, we'll be building a comprehensive security prompt that you can use with any AI coding assistant. Each takeaway will be formatted as a code block that we'll compile at the end.
1. Hardcoded Secrets: The Silent Killers
The Problem: AI coding assistants often generate code with hardcoded API keys, passwords, and tokens. It's faster to include them directly in the code, but this creates a massive security vulnerability that's easy to miss when you're focused on functionality.
Why It's Dangerous: Hardcoded secrets are like leaving your house keys under the doormat. Anyone with access to your code (including version control history) can steal your credentials. This includes:
- API keys and tokens
- Database passwords
- Private keys
- OAuth secrets
- Third-party service credentials
How to Fix Them:
// ❌ AI often generates this
const apiKey = "sk-1234567890abcdef";
const dbPassword = "super_secret_password";
const stripeKey = "sk_test_1234567890";
// ✅ Fix it like this
const apiKey = process.env.API_KEY;
const dbPassword = process.env.DB_PASSWORD;
const stripeKey = process.env.STRIPE_SECRET_KEY;
// Create a .env file
// API_KEY=sk-1234567890abcdef
// DB_PASSWORD=super_secret_password
// STRIPE_SECRET_KEY=sk_test_1234567890
// Add to .gitignore
echo ".env" >> .gitignore
echo ".env.local" >> .gitignore
Security Takeaway #1:
NEVER hardcode secrets in your code.
Always use environment variables and keep them out of version control.
What to look for:
- String literals that look like API keys, passwords, or tokens
- Database connection strings with embedded credentials
- OAuth client secrets or private keys
- Any sensitive data that shouldn't be in your codebase
2. No Input Validation: The Gateway to Chaos
The Problem: AI often generates code that directly uses user input without validation. It's faster to skip the validation step, but this creates multiple attack vectors that can compromise your entire application.
Why It's Dangerous: Unvalidated input is the primary attack vector for:
- SQL Injection: Malicious SQL code injected through form inputs
- XSS (Cross-Site Scripting): Malicious JavaScript executed in users' browsers
- NoSQL Injection: Similar to SQL injection but for NoSQL databases
- Command Injection: System commands executed through input fields
- Path Traversal: Access to files outside intended directories
How to Fix Them:
// ❌ AI often generates this
app.post('/user', (req, res) => {
const { name, email } = req.body;
const query = `INSERT INTO users (name, email) VALUES ('${name}', '${email}')`;
db.query(query);
});
// ✅ Fix it like this
import Joi from 'joi';
import { escape } from 'html-escaper';
const userSchema = Joi.object({
name: Joi.string().min(1).max(100).required(),
email: Joi.string().email().required()
});
app.post('/user', (req, res) => {
const { error, value } = userSchema.validate(req.body);
if (error) return res.status(400).json({ error: error.details[0].message });
const { name, email } = value;
const query = 'INSERT INTO users (name, email) VALUES (?, ?)';
db.query(query, [name, email]);
});
// For frontend, escape HTML output
document.getElementById('username').innerHTML = escape(userInput);
Security Takeaway #2:
ALWAYS validate and sanitize user input.
Use parameterized queries, escape HTML output, and implement proper validation schemas.
Never trust user input, even from authenticated users.
What to look for:
- Direct string interpolation in database queries
- innerHTML assignments with user data
- eval() or similar dynamic code execution
- File operations using user-provided paths
- Missing validation middleware on API endpoints
3. Missing Authentication: The Open Door Policy
The Problem: AI often generates API endpoints and admin routes without any authentication checks. It's faster to skip the auth setup, but this leaves your sensitive data completely exposed to anyone who knows the URL.
Why It's Dangerous: Without proper authentication, you're essentially running a public service. Attackers can:
- Access sensitive data and functionality
- Modify or delete critical information
- Impersonate other users
- Escalate privileges
- Bypass authorization checks
- Send lots of requests, blowing up your usage costs
How to Fix Them:
// ❌ AI often generates this
app.get('/admin/users', (req, res) => {
const users = db.query('SELECT * FROM users');
res.json(users);
});
// ✅ Fix it like this
import jwt from 'jsonwebtoken';
const authenticateToken = (req, res, next) => {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (!token) return res.status(401).json({ error: 'Access token required' });
jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
if (err) return res.status(403).json({ error: 'Invalid token' });
req.user = user;
next();
});
};
app.get('/admin/users', authenticateToken, (req, res) => {
const users = db.query('SELECT * FROM users');
res.json(users);
});
// For frontend, protect routes
const ProtectedRoute = ({ children }) => {
const { user, loading } = useAuth();
if (loading) return <div>Loading...</div>;
if (!user) return <Navigate to="/login" />;
return children;
};
Security Takeaway #3:
IMPLEMENT authentication from day one.
Use existing auth solutions like Supabase, Clerk, or Auth0.
Use JWT tokens, session management, and proper middleware.
NEVER expose sensitive endpoints without authentication.
What to look for:
- API routes without authentication middleware
- Admin panels or sensitive pages without login checks
- Database queries that don't verify user permissions
- Missing session validation in protected routes
- Frontend routes that should be protected but aren't
4. Insecure Dependencies: The Trojan Horses
The Problem: AI often suggests packages without considering their security implications. It's faster to install whatever works, but vulnerable dependencies can give attackers access to your entire system.
Why It's Dangerous: Vulnerable dependencies can:
- Execute arbitrary code on your server
- Access sensitive data
- Modify your application's behavior
- Create backdoors for persistent access
- Compromise your entire infrastructure
How to Fix Them:
# ❌ AI often suggests this
npm install some-random-package
# No security checks, no updates
# ✅ Fix it like this
# 1. Check package reputation and maintenance
npm info some-package
npm view some-package time
# 2. Run security audits
npm audit
npm audit fix
# 3. Use Rafter to audit your dependencies! We do automatically in every scan.
Security Takeaway #4:
REGULARLY audit your dependencies.
Keep packages updated, remove unused dependencies, and never install packages without checking their security.
What to look for:
- Outdated packages with known vulnerabilities
- Packages with no recent updates or maintenance
- Dependencies you don't actually use
- Packages from untrusted sources
- Missing security audit scripts in package.json
5. No Rate Limiting: The DoS Doorway
The Problem: AI often generates API endpoints without any rate limiting. It's faster to skip the rate limiting setup, but this leaves your server vulnerable to denial-of-service (DoS) attacks and abuse.
Why It's Dangerous: Without rate limiting, attackers can:
- Overwhelm your server with requests (DoS attacks)
- Exhaust your database connections
- Consume all your bandwidth
- Make your service unavailable to legitimate users
- Cost you money through excessive resource usage
How to Fix Them:
// ❌ AI often generates this
app.post('/api/process', (req, res) => {
// Expensive operation without rate limiting
const result = processLargeData(req.body);
res.json(result);
});
// ✅ Fix it like this
// Configure limits in your platform. Vercel, for example, makes it easy.
// Or use a library like express-rate-limit.
import rateLimit from 'express-rate-limit';
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
message: 'Too many requests from this IP, please try again later.',
standardHeaders: true,
legacyHeaders: false,
});
app.use('/api/', limiter);
// For specific endpoints
const strictLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5,
message: 'Too many requests, please try again later.'
});
app.post('/api/process', strictLimiter, (req, res) => {
const result = processLargeData(req.body);
res.json(result);
});
// For database operations
const dbLimiter = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 10, // 10 database operations per minute
keyGenerator: (req) => req.user?.id || req.ip
});
Security Takeaway #5:
IMPLEMENT rate limiting on all API endpoints.
Use your platform's rate limiting features or a library like express-rate-limit.
Use different limits for different operations.
Consider user-based limiting for authenticated endpoints.
What to look for:
- API endpoints without rate limiting middleware
- Expensive operations that could be abused
- Missing rate limiting on authentication endpoints
- Database operations without request limits
- File upload endpoints without size/rate limits
How Rafter Keeps Builders Safe
At Rafter, we understand the tension between speed and security. That's why we've built tools that make security a natural part of your development workflow, not a roadblock.
Automated Security Scanning
- Scan your codebase for vulnerabilities automatically
- Get actionable security insights in minutes
- Integrate security checks into your CI/CD pipeline
Actually Useful Security Insights
- Identify security issues before they reach production
- Understand the impact and severity of each issue
- Copy-paste fixes into your favorite AI coding assistants
Developer-Friendly Security
- Clear, actionable security recommendations
- No security expertise required
- Focus on building while we handle security
Building Security Into Your Vibe
Here's how to maintain your coding momentum while staying secure:
1. Start with Security Basics
- Use secure authentication from day one
- Validate all user inputs
- Keep dependencies updated
2. Automate Security Checks
- Integrate Rafter into your workflow
- Run security scans on every commit
- Get alerts for new vulnerabilities
3. Make Security Part of Your Routine
- Review security reports regularly
- Fix high-priority issues immediately
- Plan security improvements alongside features
4. Learn as You Build
- Use Rafter's security insights to learn
- Understand why vulnerabilities matter
- Build security knowledge incrementally
Your Complete Security Prompt
Here's the comprehensive security prompt you can use with any AI coding assistant. It combines all the takeaways from this article:
You are a security-focused coding assistant. When reviewing or generating code, always ensure:
1. SECRETS MANAGEMENT:
- NEVER hardcode secrets in your code
- Always use environment variables and keep them out of version control
- Look for: String literals that look like API keys, passwords, or tokens; Database connection strings with embedded credentials; OAuth client secrets or private keys; Any sensitive data that shouldn't be in your codebase
2. INPUT VALIDATION:
- ALWAYS validate and sanitize user input
- Use parameterized queries, escape HTML output, and implement proper validation schemas
- Never trust user input, even from authenticated users
- Look for: Direct string interpolation in database queries; innerHTML assignments with user data; eval() or similar dynamic code execution; File operations using user-provided paths; Missing validation middleware on API endpoints
3. AUTHENTICATION:
- IMPLEMENT authentication from day one
- Use JWT tokens, session management, and proper middleware
- Never expose sensitive endpoints without authentication
- Look for: API routes without authentication middleware; Admin panels or sensitive pages without login checks; Database queries that don't verify user permissions; Missing session validation in protected routes; Frontend routes that should be protected but aren't
4. DEPENDENCY SECURITY:
- REGULARLY audit your dependencies
- Keep packages updated, remove unused dependencies, and never install packages without checking their security
- Look for: Outdated packages with known vulnerabilities; Packages with no recent updates or maintenance; Dependencies you don't actually use; Packages from untrusted sources; Missing security audit scripts in package.json
5. RATE LIMITING:
- IMPLEMENT rate limiting on all API endpoints
- Use different limits for different operations, and consider user-based limiting for authenticated endpoints
- Look for: API endpoints without rate limiting middleware; Expensive operations that could be abused; Missing rate limiting on authentication endpoints; Database operations without request limits; File upload endpoints without size/rate limits
Before suggesting any code, scan for these security issues and provide secure alternatives. Always explain the security implications of your suggestions.
The Bottom Line
Vibe coding is amazing - it's making developers more productive than ever. But security isn't optional, and it doesn't have to slow you down.
With the right tools and mindset, you can maintain your coding momentum while building secure, trustworthy applications. Rafter is here to help you do exactly that.
Ready to Secure Your Vibe?
Don't let security become a roadblock. Start building securely from day one with Rafter.
- Run a Free Audit (in under 2 minutes)
- Learn More About How Rafter Works
- Read About Our Launch and Vision
This article is part of our ongoing series on developer security best practices. For more insights, check out our handbook and security resources.