DAST vs SAST for AI-Generated Apps (and Why Deployed-App Scanning Wins)

DAST vs SAST for AI-built apps: a security scanner for AI code should test the deployed app, not just read source. Here's why deployed-app scanning catches more.

Barret8 min read

You went looking for a security scanner for your AI-built app and immediately hit a wall of acronyms — DAST, SAST, "static analysis," "dynamic testing." You don't want a vocabulary lesson. You want to know which kind actually catches the things that leak data from a vibe-coded app.

Here's the short version, and then the why. There are two broad ways to scan an app: read its source code (SAST), or test the running app (DAST). Both are useful. But for apps built with AI tools, the most damaging gaps live in places that only show up when you test the deployed app the way an attacker would.

This post defines both, fairly, and explains why deployed-app scanning wins for this specific kind of app — without pretending either one does everything.

⚡ TL;DR

  • SAST reads your source code. DAST tests your running app. They catch different things, and good security uses both.
  • For AI-built apps, the worst leaks live in configuration and deployment — RLS policies, exposed live endpoints, open buckets — which you only catch by testing the deployed app.
  • A scanner that stops at security headers is doing the shallow part of DAST. The depth is in actually probing access rules and auth the way an attacker would.

SAST and DAST, in plain English

SAST stands for Static Application Security Testing. "Static" means it reads your code without running it — like a very thorough proofreader going through every line looking for known-dangerous patterns. It's the spellcheck of security: fast, runs early, and great at catching certain coding mistakes before they ship.

DAST stands for Dynamic Application Security Testing. "Dynamic" means it tests the app while it's running — it sends real requests to your live app and watches how it responds, the way an outside attacker would. It doesn't need your source code. It pokes the actual deployed thing and sees what leaks.

A useful analogy: SAST reads the blueprint of a house and flags a door drawn too narrow. DAST walks up to the finished house and tries every door and window to see which ones are actually unlocked. The blueprint can look perfect and the front door can still be wide open — because the lock got installed wrong, or the wrong key was left under the mat.

Where AI-built apps actually leak

This is the crux. The gaps that cause real breaches in vibe-coded apps mostly don't live in the source code as classic "bad lines." They live in configuration and deployment — and those are exactly what a code reader can miss.

Walk through the most common ways these apps leak:

  • Missing or USING (true) RLS policies. Whether your database tables are protected isn't really a property of your app's code — it's a property of how the database is configured. Reading the frontend source won't reliably tell you a live table is exposed. Querying it will. (See Is my Supabase exposed?.)
  • Exposed live endpoints. An API endpoint that returns data it shouldn't is only provable by calling it. The code might look reasonable; the deployed behavior is what matters.
  • Open storage buckets. A bucket's permissions are a cloud setting, not a line of code. The only honest test is trying to open a private file's URL without logging in.
  • Auth bypass and IDOR. IDOR (Insecure Direct Object Reference) means changing an ID in a request to read someone else's data. You can only confirm it by sending the request and seeing what comes back.
  • Exposed secrets in the shipped bundle. What actually reaches the browser — after the build, after deployment — is the real attack surface. (See exposed secrets & API keys.)

Notice the pattern: nearly every item is about the deployed, running app, not the code as written. The build step, the deployment config, the database settings, and the cloud permissions all sit between your source and your live app — and that's precisely the gap where AI tools leave holes. SAST reads the "before." Attackers hit the "after."

There's a reason the documented incidents look this way. The research backs it up too: one assessment of fifteen apps built across multiple AI tools found that every tool introduced a server-side request forgery (SSRF) flaw, none implemented protection against cross-site request forgery (CSRF), and none set security headers. Those are runtime, deployed-app properties — the kind DAST is built to find.

A fair word on what each catches

It would be crying wolf to tell you SAST is useless. It isn't, and a scanner that pretends otherwise is overselling.

SAST is good at: spotting dangerous code patterns early, catching certain injection bugs in logic, and reviewing code before it's ever deployed. If you have source access and want to catch a class of mistakes during development, it earns its place. Its weaknesses are the flip side: it can't see your runtime configuration, it doesn't know how your database is actually set up, and it's prone to flagging things that look risky in code but are harmless in practice (false positives).

DAST is good at: finding what's actually exposed on the live app — open endpoints, broken access rules, leaking buckets, missing headers — because it tests reality instead of intent. Its honest limitation is that it can only test what it can reach; a path it never exercises is a path it doesn't check, and it sees behavior rather than root cause in the code.

The grown-up answer is that they're complementary. But if you're a non-developer who shipped an app with an AI tool and you can only start one place, start with the one that tests what an attacker can actually reach: the deployed app.

How to check your own app

You can do a basic deployed-app check by hand — it's just tedious to do thoroughly:

  1. Query your live API as a stranger. Hit your public endpoints with only the public key, logged out. If real data comes back, that's an exposed table.
  2. Try IDOR. Logged in as yourself, change an ID in a request to one belonging to another user. If you get their data, that's a live access-control hole.
  3. Test a private file URL logged out. Open a private upload's URL in a fresh private window. If it loads, the bucket is open.
  4. Look at what shipped. Open the network tab and your JS bundle. Note any secret keys or revealing endpoints.

This is the spirit of DAST: test the running app, the way someone attacking it would.

Want a deployed-app scan without doing it by hand?

Run a free, read-only scan of your live app — no install, results in under a minute.

Scan my app free →

Not all DAST is the same depth

Here's where most scanners aimed at vibe-coders quietly stop short — and where the real difference is.

A lot of "scanners" run a shallow version of DAST: they check your security headers, note whether you're on HTTPS, maybe flag a public key, and call it a scan. Those checks aren't worthless, but they're the easy 10%. They don't touch the things that actually leak your users' data.

The depth that matters is active testing of the live behavior:

  • RLS probes — actually querying your tables as an anonymous and as a different user to see which rows come back, instead of guessing from headers.
  • Auth-bypass tests — checking whether endpoints behind public identifiers verify the user, the exact gap behind real auth-bypass incidents.
  • IDOR checks — systematically trying to access records that belong to someone else.

This is also where the brand's discipline matters: a deep scan should tell you what's real, not flag everything that looks scary. Your Supabase anon key showing up in the browser is not a vulnerability — it's public by design — and a scanner that screams about it is wasting your time and burning your trust. The valuable signal is "this table actually returns other users' rows," not "we found a key that's supposed to be there." Depth without discipline is just noise; depth with the judgment to suppress the false alarms is what's worth running.

FAQ

Do I need both SAST and DAST?

Ideally, over time, yes — they catch different things. But if you're shipping an AI-built app and starting from zero, DAST on the deployed app is the higher-leverage first move, because the gaps that cause breaches in these apps are mostly configuration and deployment issues that live testing catches and source-reading often misses.

Can a scanner test my app without my source code?

Yes — that's exactly what DAST does. It tests the running app from the outside, the way an attacker would, so it doesn't need access to your codebase. That also makes it easy to run on something you built with a no-code or low-code AI tool where you may not even have clean source to hand a SAST tool.

Isn't testing my live app risky?

A responsible scan is read-only — it checks what's exposed without changing or deleting your data, the way a careful observer would rather than a vandal. The thing that's actually risky is not knowing what your live app leaks, because an attacker will run their own, far less polite, version of the same test.

The bottom line

A security scanner for AI-built code earns its keep by testing the deployed app, not just reading source — because the worst gaps in vibe-coded apps live in configuration, RLS, exposed endpoints, and open buckets that only show up at runtime. SAST and DAST are complementary, but for this kind of app, deployed-app scanning wins, and only if it goes deeper than security headers and skips the public-key false alarms. An attacker can run this against your live app in minutes. The point is to run it first, and to keep running it, because your AI ships new code (and new holes) on every deploy.

Find your gaps before an attacker does.

Is My Site Hackable? scans your deployed app for the exact issues in this article — exposed keys, missing RLS, open buckets — and tells you what's real and what's a false alarm.

Run a free scan →