Home › Blog › SAST for AI-built SaaS

SAST for AI-built SaaS: what Semgrep catches and what it misses

October 12, 2026 · ~8 min read

If you shipped a SaaS with AI help and want to "run a SAST before launch", the first tool you'll meet is usually Semgrep. It's a great tool — and free for a lot of use. But there's a whole class of flaws, exactly the one that most often sinks a new SaaS, that it rarely catches. This is the difference, with no fluff.

First: SAST, DAST and SCA in one line each

TermWhat it isExample
SASTStatic analysis: reads the source code without running the app.Semgrep, CodeQL
DASTDynamic analysis: attacks the running app from the outside.OWASP ZAP, Burp
SCAComposition: scans your dependencies for known CVEs.npm audit, Dependabot

All three are complementary. SAST is the most dev-friendly (runs in CI, needs no environment) — which is why almost everyone starts there.

What Semgrep (and pattern SAST) catches very well

Pattern-based SAST tools (rules that match a shape of code) are excellent at flaws with a recognizable "face":

For that kind of thing, run Semgrep in your CI today. It's cheap, guaranteed value.

What slips through — and why

Pattern SAST hits its limit when the flaw isn't a wrong snippet but a missing or misapplied business rule. To see that, the tool would need to understand the code's intent, not just its shape. Examples:

1. Broken authorization (IDOR / BOLA)

This endpoint is syntactically perfect. No pattern rule complains:

app.get('/orders/:id', auth, async (req, res) => {
  const order = await db.orders.findById(req.params.id);
  res.json(order); // ❌ never checks the order belongs to the user
});

The user is "logged in" (passed auth), but anyone swaps the :id and reads other people's orders. To pattern SAST this is ordinary code — the flaw is the line that isn't there (the ownership check), and patterns can't see absence. It's #1 on the OWASP API Top 10 and the top data-leak in multi-tenant SaaS.

2. Database access rules (Firestore / Supabase RLS)

In stacks like Firebase and Supabase, much of your security isn't in your TypeScript — it's in firestore.rules or your Postgres RLS policies. Your app's SAST doesn't even look at those files, and one open rule there exposes the database directly, bypassing your code entirely. (We wrote a whole guide on it: the 7 Firebase Security Rules mistakes.)

3. A client-side check that belongs on the server

The admin button disappears from the UI, but the API route stays open. Or the plan limit is enforced only in the front-end. Patterns see two correct pieces in isolation; they don't understand that trust was placed in the wrong layer.

4. Business logic and cross-file state

"Paid → unlock" with a race condition. A coupon that can be applied twice. A webhook with no idempotency. These need following a flow across several files and understanding what should happen — territory pattern rules don't reach.

The blind spot of AI-built code: an assistant ships the working feature fast, but tends to leave out exactly the ownership checks, the tenant isolation and the server-side validation. The result sails past pattern SAST — because what's missing isn't a wrong snippet, it's a check nobody wrote.

Where an AI review fits

This is where SAAS SHIELD is a complement to Semgrep, not a replacement. Instead of matching patterns, it reads the repository the way a human reviewer would: it follows the flow across files, understands who should be able to do what, and flags the missing authorization, the weak tenant isolation and the open Firestore/RLS rules. Every finding comes with its code location, evidence and fix, mapped to OWASP.

The practical combination: Semgrep in CI for patterns (secrets, injection, dangerous functions) + a logic-and-authorization review before launch. One covers the shape; the other covers the intent.

Run the authorization review before you launch

SAAS SHIELD reviews your React/Next.js repository on Firebase or Supabase and returns every flaw with its location, evidence and fix.

Request an audit →