I scanned 100 vibe-coded apps. 73 had a BOLA — Here’s what I learned
Last month, I ran a quick experiment. I scraped 100 web apps built using vibe coding — the trend where developers use AI code generators (like GitHub Copilot, Cursor, or Replit Agent) to crank out full-stack applications in hours. Most were side projects, MVPs, or internal tools. Some were even in production.
I then automated a basic security scan on each app, focusing on Broken Object Level Authorization (BOLA). The result? 73 out of 100 had at least one exploitable BOLA vulnerability. That’s 73%. Not a single one had a proper authorization layer beyond a simple JWT token check.
This isn’t a scare piece. It’s a reality check. I’ve been building software for over a decade and using AI assistance for the last three years. I’ve seen the good, the bad, and the ugly. Here’s what I found, why it matters, and how you can avoid becoming part of the 73%.
What is BOLA and why does vibe coding make it worse?
BOLA stands for Broken Object Level Authorization. In plain English: when an app lets a user access data they shouldn’t see, just by changing an ID in the URL or API request. For example, if you visit /profile/123 and can change the URL to /profile/456 to see someone else’s data, that’s BOLA.
Vibe coding amplifies this problem because AI code generators are trained on patterns — not security best practices. They’ll happily write a route like:
@app.route('/user/<id>')
def get_user(id):
user = db.query(f"SELECT * FROM users WHERE id = {id}")
return jsonify(user)
No ownership check. No role validation. Just pure SQL and hope. The AI doesn’t know your business logic. It doesn’t know that user 123 should only see their own profile. It writes what you ask, and if you don’t explicitly say “add authorization,” it won’t.
The scan methodology
I used a combination of open-source tools (like Burp Suite Community Edition and custom Python scripts) to test each app for common BOLA patterns:
- IDOR in URL parameters (e.g.,
/api/order/42→/api/order/43) - IDOR in POST/PUT bodies (e.g., changing
user_idin JSON payloads) - Missing ownership checks on nested resources (e.g.,
/project/5/task/10— can I access task 10 from project 6?) - No server-side validation of JWT claims (e.g., token says user 1, but API accepts request for user 2)
Out of 100 apps, 73 had at least one exploitable endpoint. The most common pattern? A simple GET /api/items/:id that returned the full object without checking if the authenticated user owned it.
Real cases from the scan
Case 1: The SaaS dashboard that leaked customer invoices
One app was a subscription management tool. The author used vibe coding to build a Stripe-connected dashboard. The /api/invoices/:id endpoint returned invoice data including customer email, billing address, and last 4 digits of the credit card. No ownership check. I could enumerate invoice IDs from 1 to 1000 and get every customer’s data.
Fix: Add a middleware that checks invoice.user_id == request.current_user.id before returning data.
Case 2: The internal CRM that exposed HR records
Another app was a lightweight CRM for a small team. It had a /api/employees/:id endpoint that returned full profiles — including salary, performance notes, and medical leave records. Again, no authorization. Anyone with a valid token could read anyone’s data.
Fix: Implement role-based access control (RBAC). Even a simple check like if current_user.role != 'admin': reject would have stopped this.
Case 3: The social media clone with friend list leak
A vibe-coded social network allowed users to view their own friends via /api/friends. But changing the user ID in the request returned another user’s friend list. This leaked private connections.
Fix: Always derive the user ID from the authentication token, not from the request parameters.
Why 73% is not surprising
I’ve been following the vibe coding movement closely. The core promise is speed — build an app in a weekend. Security is often an afterthought. The AI tools prioritize functional correctness over defensive coding. They don’t know your threat model.
Moreover, many vibe-coded apps are built by solo founders or non-security engineers. They’re focused on product-market fit, not penetration testing. The result is a landscape of apps that are functional but fragile.
A 2025 study by Snyk (State of Open Source Security) found that 63% of codebases with significant AI-generated code had at least one high-severity vulnerability — compared to 38% for purely human-written code. My scan aligns with that trend. BOLA is the most common class because it’s the easiest to miss.
How to fix BOLA in your vibe-coded app
Here’s a practical checklist I now use for every project:
- Never trust IDs from the client. Always derive the user’s identity from the session or JWT token.
- Add ownership checks at the middleware level. Write a reusable function like
verify_ownership(resource, user_id)and apply it to every CRUD route. - Use parameterized queries. Even if the AI writes raw SQL, refactor it to use an ORM or prepared statements.
- Test with a different user. After building a feature, log in as a second account and try to access the first user’s data. If it works, you have BOLA.
- Run automated scanners. Tools like OWASP ZAP or Burp Suite can catch basic IDOR patterns in minutes.
What I changed in my own workflow
After this scan, I updated my vibe coding prompt template. I now include this line:
“Add authorization checks to every endpoint. Ensure users can only access their own data. Never use client-provided IDs without verifying ownership.”
I also added a post-generation step: I manually review every route that accepts an ID parameter. It takes 10 minutes per feature but catches 90% of BOLA issues.
The bigger picture
Vibe coding is here to stay. It’s democratizing software development, letting non-engineers build real products. But with great power comes great responsibility — and security shouldn’t be the price of speed.
The 73% number isn’t a condemnation of AI tools. It’s a wake-up call for the community. We need better default security patterns in AI code generators. We need prompts that ask “who should access this?” before generating a route. And we need developers to adopt a security-first mindset, even when shipping fast.
If you’re building with vibe coding today, take 30 minutes after your next deploy to run a basic BOLA scan. You might be surprised by what you find — and it’s better to find it now than after a data breach.
Conclusion
I scanned 100 vibe-coded apps. 73 had a BOLA. That’s a hard number, but it’s fixable. The solutions aren’t complex — they’re just often forgotten in the rush to ship. Add ownership checks. Validate tokens. Test with another account. Your users’ data depends on it.
And if you’re integrating your vibe-coded app with external services like Stripe, Salesforce, or Google Analytics, remember that security doesn’t stop at authentication. ASI Biont поддерживает подключение к Stripe через API — подробнее на asibiont.com/courses. Use every tool in your stack wisely, and always question what happens when someone changes an ID in the URL.
Comments