5 Critical Security Vulnerabilities in Bolt.new Apps (And How to Fix Them)
Bolt.new has revolutionized how we build web applications. With AI-powered code generation, you can go from idea to deployed app in minutes. But this speed comes with security trade-offs that every developer needs to understand.
After scanning hundreds of Bolt.new applications, we've identified the most common security vulnerabilities that put apps and their users at risk. In this guide, we'll walk through each vulnerability and show you exactly how to fix it.
Exposed API Keys in JavaScript Bundles
Critical Risk
Attackers can extract API keys in seconds using browser DevTools
This is the most common vulnerability we see in Bolt.new apps. When you ask Bolt to integrate with OpenAI, Stripe, or other services, it often hardcodes the API key directly in your frontend code.
// Bad: API key exposed in client-side code
const openai = new OpenAI({
apiKey: "sk-proj-abc123..."
});
How to Fix It
- Move API calls to server-side API routes or edge functions
- Store API keys in environment variables (never prefix with NEXT_PUBLIC_)
- Use Vercel's encrypted environment variables for production
// Good: API route that keeps key server-side
// app/api/chat/route.ts
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY
});
Missing Supabase Row Level Security (RLS)
Critical Risk
Anyone with your anon key can read and modify all database records
Bolt.new apps frequently use Supabase for the backend. The problem? AI-generated code almost never sets up Row Level Security policies. This means your Supabase anon key (which is public) gives anyone full access to your database.
How to Check If You're Vulnerable
Open your browser's DevTools, find your Supabase URL and anon key, then try this in the console:
const { createClient } = supabase;
const client = createClient(SUPABASE_URL, ANON_KEY);
const { data } = await client.from('users').select('*');
// If this returns data, you're vulnerable
How to Fix It
- Enable RLS on every table:
ALTER TABLE tablename ENABLE ROW LEVEL SECURITY; - Create policies that restrict access based on
auth.uid() - Test your policies by trying to access data as an unauthenticated user
Missing Security Headers
AI-generated apps rarely include security headers. This leaves your app vulnerable to XSS attacks, clickjacking, and other client-side exploits. The most important missing headers are:
- Content-Security-Policy (CSP) - Prevents XSS by controlling which scripts can run
- X-Frame-Options - Prevents clickjacking attacks
- Strict-Transport-Security (HSTS) - Forces HTTPS connections
- X-Content-Type-Options - Prevents MIME type sniffing
How to Fix It
Add security headers in your next.config.js or vercel.json:
// next.config.js
headers: async () => [{
source: '/:path*',
headers: [
{ key: 'X-Frame-Options', value: 'DENY' },
{ key: 'X-Content-Type-Options', value: 'nosniff' },
{ key: 'Strict-Transport-Security', value: 'max-age=31536000' },
]
}]
Exposed .env Files
Sometimes configuration files get accidentally deployed to production. A publicly accessible .env file exposes all your application secrets at once.
How to Check
Try accessing these URLs on your production domain:
- yourapp.com/.env
- yourapp.com/.env.local
- yourapp.com/.env.production
How to Fix It
- Add
.env*to your.gitignore - Use your hosting platform's environment variable settings
- Rotate any secrets that may have been exposed
Source Map Exposure
Source maps help with debugging but expose your entire source code to anyone who looks. Attackers can use this to understand your application logic and find additional vulnerabilities.
How to Fix It
Disable source maps in production by updating your Next.js config:
// next.config.js
module.exports = {
productionBrowserSourceMaps: false,
}
Scan Your Bolt.new App for Vulnerabilities
VAS automatically checks for all these vulnerabilities and more. Get a comprehensive security report in minutes, not hours.