If you've spent any time reading about web security, you've probably seen "OWASP Top 10" mentioned. It sounds technical and intimidating. It's actually one of the most practical things you can learn as a founder — because it maps directly to the vulnerabilities that show up in AI-generated apps.
OWASP (the Open Web Application Security Project) publishes a list of the ten most critical web security vulnerabilities. Security professionals use it as a checklist. Attackers use it as a playbook.
This guide walks through each one in plain English, with a specific example of how it shows up in vibe-coded apps — the kind built with Lovable, Bolt.new, Cursor, v0, Replit, or Windsurf.
1. Broken Access Control
What it means: Users can access data or perform actions they shouldn't be allowed to.
In vibe-coded apps: Your AI tool built a route like /api/users/[id]/profile that returns a user's full profile. The problem: it doesn't check whether the logged-in user is allowed to see that profile. Anyone who knows (or guesses) a user ID can request any user's data.
This is the #1 vulnerability worldwide. In Lovable apps with Supabase, it often shows up as Row Level Security being disabled — meaning any authenticated user can read every row in every table.
What to look for: Any API route that returns user data should filter by the currently authenticated user. "Show me my data" should never be "show me any user's data based on a URL parameter."
2. Cryptographic Failures
What it means: Sensitive data is not properly protected — either it's transmitted unencrypted or stored without proper encryption.
In vibe-coded apps: Your app collects user email addresses, and stores them in a database column with no encryption. If your database is ever breached, those emails are immediately readable. More immediately: if your app doesn't enforce HTTPS, data between your users and your server travels in plaintext.
Replit apps on custom domains are particularly vulnerable to the HTTPS version of this problem — SSL configuration is often missed.
What to look for: Every page should load over HTTPS. Any sensitive field in your database (payment data, health information, private messages) should be encrypted at rest. Never transmit passwords in plaintext.
3. Injection
What it means: An attacker tricks your app into running malicious code by putting it inside user input.
In vibe-coded apps: Your app has a search feature. The AI generated a database query that looks like:
const results = await db.query(`SELECT * FROM posts WHERE title LIKE '%${searchTerm}%'`)
An attacker enters '; DROP TABLE posts; -- as the search term. The query becomes SELECT * FROM posts WHERE title LIKE '%'; DROP TABLE posts; --'. Your entire posts table is deleted.
This is SQL injection. Similar attacks exist for HTML (XSS — Cross-Site Scripting) and command execution.
What to look for: Never build database queries by concatenating user input with strings. Use parameterized queries or an ORM that handles this automatically (Prisma, Drizzle, Supabase's query builder). Always sanitize HTML inputs before displaying them.
4. Insecure Design
What it means: The fundamental design of the feature is flawed — not just the implementation.
In vibe-coded apps: Your app sends a password reset link via email. The link contains the user's email address and a timestamp. An attacker can reset anyone's password by constructing a link with their email — the link doesn't include a secret token that proves ownership of the email.
This isn't a bug you can patch — it's a design flaw that requires rebuilding the feature.
What to look for: Password reset flows should use a random, single-use, time-limited token stored server-side. "I forgot my password" features should always send a secret to the email address, not just accept an email as proof of identity.
5. Security Misconfiguration
What it means: Secure features exist but aren't turned on. Default settings that are fine for development are left on in production.
In vibe-coded apps: This is the most common category for AI-built apps. Examples:
- CORS set to
*(allows any website to call your API) - Security headers not configured (X-Frame-Options, CSP, HSTS missing)
- Debug mode or verbose error messages left on in production
- Supabase RLS disabled because it was turned off during development
- Replit repls left public when they contain secrets
What to look for: Run VibeScan to automatically check for the most common misconfigurations. Pay special attention to your deployment's header configuration and CORS settings.
6. Vulnerable and Outdated Components
What it means: Your app uses third-party packages with known security vulnerabilities.
In vibe-coded apps: Your AI tool added ten npm packages to build various features. One of them — maybe an image processing library or a PDF generator — has a known vulnerability that was patched six months ago. You're still running the old version.
This is a background risk that grows over time. Even a secure app can be compromised through a dependency.
What to look for: Run npm audit (or yarn audit) periodically to check for known vulnerabilities in your dependencies. Pay attention to security advisories for any major packages you use. Keep dependencies updated.
7. Identification and Authentication Failures
What it means: Your login system can be bypassed or exploited.
In vibe-coded apps: Your app doesn't limit how many times someone can try a password. An attacker writes a script that tries 10,000 common passwords against an account in minutes. This is a brute-force attack — and it works on any login without rate limiting.
Other common versions: JWTs that never expire, sessions that aren't invalidated on logout, "remember me" cookies that last forever.
What to look for: Your login endpoint should have rate limiting. Sessions should expire. Logout should actually invalidate the session server-side, not just delete a cookie. Supabase and NextAuth handle many of these correctly by default — but verify you haven't overridden the defaults.
8. Software and Data Integrity Failures
What it means: Your app trusts data or code it shouldn't, or doesn't verify that updates are legitimate.
In vibe-coded apps: Your app loads a JavaScript library from a CDN using a <script> tag without a Subresource Integrity (SRI) hash. If that CDN is compromised, the attacker can serve malicious JavaScript to all your users — and your app will run it.
Less dramatically: your app accepts user-supplied JSON and processes it without validation. An attacker sends data with extra fields that your app treats as authoritative.
What to look for: Add SRI hashes to any external scripts. Validate the structure and types of any data you receive before processing it. Never trust client-supplied data to determine server-side permissions.
9. Security Logging and Monitoring Failures
What it means: When something goes wrong, you have no record of it — and no way to detect that it happened.
In vibe-coded apps: An attacker tried 500 passwords on your most active user's account over 3 days. They succeeded on day 3. A month later, the user notices suspicious activity and tells you. You have no logs, no alert, nothing to investigate. You don't know what data was accessed, how long the attacker had access, or how they got in.
This doesn't help attackers get in — but it makes breaches invisible until the damage is done.
What to look for: Log authentication events (login attempts, failures, password resets). Log access to sensitive data. Set up an alert if you see unusual spikes in failed logins. Vercel and most hosting platforms give you basic request logs — know where they are.
10. Server-Side Request Forgery (SSRF)
What it means: An attacker tricks your server into making HTTP requests to internal systems that should only be accessible from inside your infrastructure.
In vibe-coded apps: Your app has a feature that fetches content from a URL the user provides (a link preview, image importer, or webhook tester). An attacker provides http://169.254.169.254/latest/meta-data/ — a special IP address that returns AWS instance metadata including credentials when accessed from within AWS infrastructure.
This is less common in simple vibe-coded apps, but any feature that makes server-side HTTP requests to user-provided URLs is potentially vulnerable.
What to look for: If your app fetches URLs from user input, validate that the URL is an expected public URL. Block requests to private IP ranges (10.x.x.x, 192.168.x.x, 172.16.x.x, 169.254.x.x, localhost).
The pattern to notice
Reading through this list, you'll notice that most OWASP vulnerabilities in vibe-coded apps have the same root cause: the AI generated code that works, not code that's secure by default.
Access controls weren't added because the feature worked without them. Input validation was skipped because the happy path worked. CORS was set to wildcard because it made development easier.
Security is the gap between "working code" and "safe code." AI tools fill the first gap brilliantly. The second gap is yours to fill.
The fastest way to start: run VibeScan to see what's exposed in your live app right now. The scan catches misconfigurations, exposed secrets, and missing headers — the highest-impact fixes that require no code changes at all.