Skip to content
NUEXUS Technologies
All insights
Engineering Jul 11, 2026· 8 min read·NUEXUS

What an Attacker Checks First on Your Vibe-Coded App

A fast-built app ships in a weekend. An attacker maps its weak points in minutes. Here is the exact order they probe, and how to close each gap before you launch.

What an Attacker Checks First on Your Vibe-Coded App

An attacker does not care how quickly you built your app. They care that it was built quickly. Fast-built, AI-generated software follows patterns, and patterns are a map. When someone hostile lands on your login page, they are not admiring the UI. They are running a checklist, and the first five items on that checklist are almost always missing on an app that went from idea to production in a weekend.

We run offensive engagements against exactly these apps. The findings repeat so often they feel scripted. Here is the order an attacker actually works through, and what you close before you hand them anything.

The database key that walks around every rule

The first thing worth checking is whether your security policies protect anyone at all.

Row-level security is the feature everyone reaches for. Tenant isolation on every table, role checks on every row, the database refusing to hand back data that does not belong to the caller. Written properly, it is a firewall at the data layer: even if your application code forgets a WHERE clause, the database still protects the row. That is the difference between a policy and a prayer.

Then someone builds an API route that connects with the service-role key. That key bypasses every policy you wrote. Your careful isolation now protects an audience of nobody, because the one route the attacker finds is the route where the admin key already unlocked every row of every tenant. In our reviews this is one of the most common holes in vibe-coded apps.

Attackers do not knock on the front door your policies are guarding. They look for the side route where the service key does the work.

  • Audit every path to the data, not just the policies on the tables.
  • Any route that connects with an admin or service key where it should use the caller's scoped identity is a finding. Fix it to use the caller's identity.
  • Treat row-level security as your last line of defence, not your only one.

Change the ID, read the tenant

Once an attacker is authenticated as a legitimate low-value user, the next move is to see whose data they can reach that is not theirs.

This is the test we run on every engagement, and you can run it against yourself. Intercept your own requests and change the values that identify you: the user_id in the path, the org_id in the body, the role claim inside the JWT. Then watch what comes back. If changing an ID in a request returns another user's records, or reaches an admin endpoint, your authorization has holes and row-level security alone was never going to save you, because the API handed unchecked parameters straight to the database.

The nightmare version of this is multi-tenant leakage: tenant A pulls tenant B's data because a query missed its tenant filter or a cache key dropped the tenant context. The technical fix is the smallest part of the damage. The real cost is legal exposure and the trust that never comes back once customer B leaves and tells their whole network.

Two structural fixes matter more than any single patch:

  • Enforce permissions at the API layer, on every route. A hidden button in the front end is a suggestion, not access control. A fetch skips your UI entirely.
  • Build permissions first and let roles be collections of them, with scope attached. "Can edit any document" and "can edit only their own document" are different rules, and an attacker will find out which one you actually enforce.

The front end is a display layer, never a trust layer. Pricing logic in JavaScript, role checks in React, and feature gates in the browser are all readable by anyone who opens developer tools. Move every business rule to the back end. Validate twice: once in the front end for a smooth experience, once in the back end because that is the only place a rule is enforced.

The secrets and tokens collected for free

While probing, an attacker is also collecting anything you left lying around. Most fast-built apps leak more than the builder realises.

Start with your bundle. Search your production build for API routes, keys, internal endpoints, and config. Framework variables prefixed for public exposure, such as NEXT_PUBLIC_ or VITE_, ship straight to the browser. Know exactly which ones you have shipped, because the attacker already read them.

Then your git history. A secret that was committed and later deleted still lives in the diff forever. Run a secret scanner over your full history today, not just your current files. Environment variables are not secrets management either: a .env file is fine on your laptop, but in production it is plaintext readable by anyone with server access. A real secrets manager encrypts at rest, controls access by role, and logs every read. That audit trail is the point. Rotate on a schedule before a breach, not after one. A key left unchanged for months is a bet that nobody found it.

Tokens are their own category. JSON Web Tokens carry vulnerabilities that have been exploited in production for years:

  • The none algorithm. Some libraries accept a token that declares its algorithm as none, meaning no signature and no verification. Anyone can then forge a token your server trusts. Confirm your library explicitly rejects it.
  • Algorithm confusion. Your server expects RSA, an attacker signs with HMAC using your public key as the secret, and if the library lets the token pick the algorithm, the forged token verifies. The fix is one line: specify the algorithm yourself.
  • No expiry. A token that never expires is a permanent key the moment it is stolen. Use short lifetimes with refresh tokens, and rotate refresh tokens on every use so a stolen one works once instead of forever.

The headers and limits nobody set

Now the attacker checks whether the app defends itself at the edges, and on fast-built apps the answer is usually no, because the app "works without them." So does the attack.

Security headers. A Content Security Policy whitelists which domains may run scripts in your users' browsers and blocks the rest. One malicious script on one compromised CDN can hijack every session, and a policy stops it before it executes. Roll it out in report-only mode first to see what breaks, then enforce. Pair it with CORS set to specific origins, never to a wildcard. Setting CORS to allow everything tells the browser you trust every website on the internet to call your API with your users' cookies. That is not configuration, it is surrender.

Rate limiting. This is architecture, not a single number on an endpoint. A flood of requests a second against one endpoint is probing, not usage, and it should be caught in middleware before your business logic ever sees it. Layer it: hard limits to stop abuse, adaptive limits that tighten under load, and tiered limits that double as your pricing model. Bots get blocked before they reach the limiter.

AI endpoints especially. A public endpoint that calls a model is one bot and one loop away from a runaway bill over a weekend. Put authentication in front of the model so no key means no tokens burned, cap spend per user, and reject oversized payloads before they reach the model at all.

Close it before someone opens it

Everything above is findable with tools you can run yourself, which means it is findable by the bots already scanning the internet for it.

Independent studies keep finding vulnerabilities in a large share of code produced by current AI coding assistants, and real production outages have been traced back to AI-generated code. The question was never whether your app has vulnerabilities. It does. The question is whether you scan for them on every single commit. And remember that the input surface now includes what your AI reads: a real Copilot remote-code-execution flaw came from a hidden prompt injection in a pull request description, not from code.

Before you launch:

  • Run an open-source scanner such as OWASP ZAP across every page, form, and API. It covers most of what a small team needs and finds the same holes the bots look for.
  • Add dependency and secret scanning to CI so it runs on every push, not once a quarter.
  • Attack your own API by changing IDs and role claims, and confirm you cannot reach another tenant.
  • Book a deeper manual pass, with a tool like Burp Suite, before any major launch.

Triage findings by severity. Injection, authentication bypass, and data exposure end companies. Lows and mediums are not emergencies. Fix in that order, and fix before launch, not after the first incident.

Get the playbook

We have packaged this into a free PDF, The Security Layer, with the full pre-launch checklist, the self-attack steps for testing your own authorization, and the header and secrets configuration an attacker checks first. It is written to be worked through in an afternoon before you ship.

It is part of our wider engineering series at /resources, where each guide takes one layer of the production stack and shows how to close it. Grab it, run it against your app, and take the easy wins away from whoever finds you next.

Build it right.
Secure it for good.

Tell us what you're building or securing. We'll bring the engineers, the security team and the trainers, plus a clear, costed plan to get you there.

AI-powered cybersecurity 24/7 expert support Trusted across industries

Join our newsletter

Be up to date with everything about NUEXUS

By subscribing you agree with our Privacy Policy