COMPREHENSIVE SECURITY FOR AI-BUILT APPS

Better models won't secure the apps your users build. They move the risk upward.

Comprehensive coverage for every app your users ship — where every finding is proven, a verified fact, or a clearly-flagged candidate. The serious risks aren't just flagged; we prove them by safely running the exploit.

PROVEN · VERIFIED FACT · FLAGGED CANDIDATE — SECURITY YOU CAN TRUST


BUILT ON · PARTNERED WITH

Built for proof. Backed by AdaptiveGRC.

VulX runs on infrastructure built for machine-speed, isolated, repeatable verification. Anthropic Claude reasons about exploitability and writes the fixes; E2B gives every exploit a disposable sandbox; Temporal orchestrates the work; Railway and Firebase run the platform. And AdaptiveGRC — an enterprise governance, risk and compliance platform — has partnered with us to bring proof-based security for AI-generated code to regulated enterprises. These are the tools we're built on and the partners we go to market through — not customers, and we won't pretend otherwise.

Anthropic
E2B
Temporal
Railway
Firebase
AdaptiveGRC
C and F
Esquercus

01THE PROBLEM

AI writes the code. Nobody audits it. And the most dangerous hole is a data leak nobody checks.

The risks run from exposed keys and vulnerable dependencies to the one that ends companies: user A can read user B's data.

AI-built apps ship a whole range of risk: a hardcoded key, a leaked service-role key, a public storage bucket, a hallucinated package import, a dependency with a known CVE — most of those you can read straight off the code as plain facts. The dangerous one is quieter. When a model generates an API route, it builds the happy path — fetch the record, return it. What it routinely forgets is the question only your business can answer: is this person allowed to see this? That gap is broken authorization (IDOR / broken object-level authorization), and it's the quiet default failure mode of vibe-coded software. It doesn't crash. It doesn't show up in a demo. It just silently hands over other people's data. This is the class behind the breaches people actually remember.

  • The model writes "fetch order by id" — and skips "check this order belongs to you."
  • It doesn't throw an error, so it ships. It surfaces as a breach, not a bug report.
  • A smarter model doesn't fix it — it can't know your access rules, so it guesses the same way.
  • Tea, Lovable, Moltbook — different apps, same root cause: code that doesn't enforce who's allowed to see what — the one class we don't just flag, we prove.
Tea Lovable Moltbook widely-reported · failure class, not VulX incidents
app/api/orders/[id]/route.ts BEFORE
export async function GET(req, { params }) {
  // fetch the order by id…
  const { data } = await supabase
    .from('orders')
    .select('*')
    .eq('id', params.id)
  // MISSING: .eq('owner_id', session.user.id)
    .single()

  // returns ANY user's order →
  return Response.json(data)
}

02HOW IT WORKS / THE HACKER

For the findings that matter, the Hacker doesn't warn — it proves.

We scan the whole app for breadth. The serious risks — a stranger reading private data — we don't just flag. We prove.

The scan covers the full range — exposed keys, a leaked service-role key, public buckets, hallucinated packages, vulnerable dependencies — reported as verified facts with the exact file and line. For the highest-impact class, data leaks and broken access, the Hacker goes further. It narrows the app with ast-grep pattern matching plus parsing the app's data-access and Row Level Security rules, down to the few places the wrong user could reach private data. Then an LLM infers the intended access rule to separate genuinely exploitable from merely suspicious. Finally it proves it live: VulX connects to the app's database and has a stranger, anonymous role actually read private rows it should never see — safely, always rolled back, with a planted canary as evidence. Nothing in the proven tier reaches you on a hunch.

01
Map the candidates

ast-grep patterns + the app's access/RLS rules narrow the whole app to the few places the wrong user could reach private data.

02
LLM exploitability

Infer the intended access rule; separate "genuinely exploitable" from "looks scary."

03
Prove it live

Connect to the app database; a stranger actually reads private rows — rolled back, canary captured as evidence.

vulx://sandbox · proof
$ vulx prove --db app-postgres --table orders
[DB] connect as anon/stranger role → session=anon
SELECT * FROM orders WHERE id = 'ord_B7'  (role: anon)
← 1 row  {"id":"ord_B7","owner_id":"bob","total":"£420.00","canary":"vulx-7f3a"}
[PROOF] stranger read private data — leak CONFIRMED, canary captured

03HOW IT WORKS / THE FIXER

The Fixer has to beat the Hacker before it ships a line.

Patch → survive the re-attack → the real user still works → tests + build → pull request.

Once a serious finding is proven, the Fixer patches it — and we prove the fix won't break the app. It has to do two things: make the exact same exploit fail, and keep the legitimate user reading their own data — the control check no other tool runs. Only if both hold, the existing tests still pass, and the project still builds does the change become a pull request; otherwise it's rejected. Breadth findings and verified facts get clear remediation guidance, but only the proven class gets the proven-safe fix. Today that PR is propose-and-approve: a human merges. Full autonomy is on the roadmap, earned with track record — not assumed.

01
Patch

The Fixer writes the minimal change that closes the proven hole.

02
Re-attack

The same exploit must now fail AND the real owner must still read her own data.

03
Tests + Build

Existing tests pass and the project compiles, or the fix is rejected.

04
Pull Request

A clean, reviewable PR. You approve the merge — for now.

Draft PR #128 fix/orders-owner-scope +6 −3
fix(orders): enforce owner_id on GET /api/orders/[id]
survived re-attack — exploit now returns 403
control passed — caller still reads her own order
tests green · build green
PROPOSE-AND-APPROVE · A HUMAN MERGES · OUTCOME TRACKED

04THE ADVERSARIAL LOOP

One brain, two roles, locked in a duel.

The same intelligence attacks and defends — and the attacker is the judge of the defense.

Most security tools report and walk away. VulX closes the loop. The Hacker and Fixer draw on the same underlying model but play opposite sides, and the attacker is the one who decides whether the defense actually worked. That's why a VulX fix means something: it wasn't approved by the thing that wrote it — it was approved by the thing trying to break it. This loop is what backs the proven flagship — data leaks and broken access — that sits inside the broader whole-app scan: breadth for coverage, this duel for the findings that matter. Reproduce, fix, re-attack, ship-gate. Every cycle, we also capture the outcome: was the fix accepted, and did it hold in production. That outcome data is wired in from day one.

  • ReproduceConfirm the exploit in a sandbox.
  • FixPatch the proven exploit.
  • BattleThe Hacker re-attacks the patched code.
  • Ship-gateExploitable-before AND not-exploitable-after AND control-still-works AND tests/build pass → PR.
  • LearnRecord whether the fix was accepted and whether it held.

05THE BET

Security doesn't get solved as models improve. It relocates upward.

And the layer it relocates into gets stronger with every model release — not weaker.

The intuition is that better AI will write secure code and this whole problem evaporates. It won't — for two reasons. First, attackers hold the same models you do, so any capability that helps you defend helps them attack. Second, the bugs that actually matter are intent-dependent: authorization is about your rules — who in your app is allowed to see what — and no smarter model can close that gap, because it doesn't know your rules. So the scarce, durable thing isn't a smarter code generator. It's independent, continuous, machine-speed verification of what AI-written code actually does. Every model release makes the code more abundant and the attackers stronger — which makes that verification layer more valuable, not less.

  • Attackers hold the same models. Defensive capability is never a one-sided gain.
  • Authorization is intent-dependent. A smarter model doesn't know your access rules.
  • So verification — not generation — becomes the scarce thing.
  • Every model release strengthens the layer that proves what code really does.

A smarter model still doesn't know who's allowed to see what.


06THE MOAT

The scanner is commodity. These four things aren't.

What compounds, and why a model vendor structurally can't copy it.

Detection alone is a race to the bottom — everyone gets the same models. VulX's defensibility is in what the loop produces and where it sits, not in the act of scanning.

  • 01
    Fix-outcome data

    Which fixes were accepted and actually held in production. The model vendors structurally can't get this; we capture it on every cycle.

  • 02
    Structural independence

    The platform and the model that wrote the code can't credibly certify that same code. We're the third party that can.

  • 03
    Depth on authorization

    We go deep on the classes we actually prove — data leaks and broken access — the bugs that cause real breaches and that a better model can't fix.

  • 04
    Cross-codebase network

    An attack learned on one app preemptively patches the others. The network gets safer as it grows.


07COVERAGE + PROOF

Comprehensive coverage on the modern web stack — the serious risks proven.

TypeScript / React / Next, Postgres / Supabase, Node. Breadth you can trust as verified facts — and data leaks / broken access proven end-to-end.

We cover the whole app — exposed keys, a leaked service-role key, public storage buckets, hallucinated package imports, vulnerable dependencies — reported as verified facts with the exact file and line; everything else is clearly flagged for review, never dressed up as proven. For the class that causes real breaches — a stranger or the wrong user reading private data — we don't stop at a warning, we prove it. Today's working proof connects directly to your Supabase database and demonstrates an anonymous, stranger read of private rows. Depth on the serious class, breadth you can trust across the rest.

Frontend / API
TypeScriptReactNext.js
Data
PostgresSupabaseRLS-aware checks
Runtime
Node
Focus
Data leaks / broken access — the proven flagship
COMPREHENSIVE COVERAGE · THE SERIOUS RISKS PROVEN

08WHO IT'S FOR / PRICING POSTURE

The people a breach would kill are who pay.

Victims don't buy prevention. Founders with everything to lose do.

We're honest about who pays: not individual developers (the person who gets breached rarely buys prevention in advance). Our first paying customers are serious indie founders and small startups whose entire business a single data breach would end. They buy comprehensive security they can actually trust — the dangerous findings proven, the rest verified facts or clearly flagged, so nobody chases a false alarm on what matters. Regulated, compliance-driven teams and enterprise CISOs come later, reached through AdaptiveGRC — an enterprise governance, risk and compliance platform that partnered with us to bring proof-based AI-code security to regulated enterprises. It's a partnership and a distribution channel, not a customer logo — we won't pretend otherwise.

The paying wedge Founders & startups

The first to pay, because one breach is existential.

Later expansion Compliance & enterprise

Reached through AdaptiveGRC — our enterprise GRC partner.

Not individual developers — the victim doesn't buy prevention; we don't pretend otherwise.


09HOW WE PROVE THE SERIOUS ONES

Watch the duel that proves a data leak.

A Next.js + Supabase route that returns any order by id — proven, patched, re-attacked, shipped.

This is how we prove the flagship class — data leaks and broken access. Today's working, wired proof connects directly to your Supabase database and demonstrates an anonymous or wrong user reading private rows: safely, always rolled back, marked with a planted canary. The walk-through below is an illustrative example of that same prove → patch → re-attack → ship-gate loop shown at the code layer — a depiction of the mechanism, not a wired self-serve flow, and the numbers depict the flow, not a benchmark. Alongside this proof, the scan reports the breadth as verified facts — exposed keys, vulnerable dependencies, and more — with the exact file and line.

ILLUSTRATIVE EXAMPLE

01 The vulnerable route — broken object-level authorization

app/api/orders/[id]/route.ts — VULNERABLE EXPLOITABLE
// service-role client bypasses Row Level Security
const supabase = createClient(SUPABASE_URL, SERVICE_ROLE_KEY)

export async function GET(req, { params }) {
  // BUG: fetches by id only — never checks ownership
  const { data, error } = await supabase
    .from('orders')
    .select('*')
    .eq('id', params.id)
    .single()
  if (error) return Response.json({ error: error.message }, { status: 404 })
  return Response.json(data)   // returns ANY user's order
}

02 The Hacker proves it in a sandbox

vulx://sandbox · e2b · hack
$ vulx hack --target ./app --path /api/orders/[id]
[SCAN]   reachable: params.id (untrusted) → orders.eq('id', params.id)  [no ownership predicate]
[LLM]   intended rule: order is private to owner_id; route enforces none → EXPLOITABLE (IDOR)
[SBX]   spinning up sandbox, seeding 2 users: alice (ord_A1), bob (ord_B7)
[SBX]   POST /auth/login  [email protected]           → 200  session=sess_alice
[SBX]   GET  /api/orders/ord_B7   Cookie: sess_alice
        → 200  {"id":"ord_B7","owner_id":"bob","total":"£420.00","card_last4":"4242"}
[PROOF] Alice read Bob's order. Cross-tenant data leak CONFIRMED. Evidence: req+resp captured.
[GATE]  exploitable_before = TRUE

03 The Fixer patches — scope the query to the caller

app/api/orders/[id]/route.ts — PATCHED PATCHED
import { createServerClient } from '@/lib/supabase/server'

export async function GET(req, { params }) {
  const supabase = createServerClient()        // session-scoped client
  const { data: { user } } = await supabase.auth.getUser()
  if (!user) return Response.json({ error: 'unauthorized' }, { status: 401 })

  const { data, error } = await supabase
    .from('orders').select('*').eq('id', params.id)
    .eq('owner_id', user.id)   // FIX: scope to the caller — RLS-equivalent
    .single()
  if (error || !data) return Response.json({ error: 'forbidden' }, { status: 403 })
  return Response.json(data)
}

04 The same attack runs again — and is blocked

vulx://sandbox · e2b · re-attack
$ vulx fix --finding IDOR-orders-by-id
[FIXER]  patch: derive caller from session, scope to owner_id, 403 on mismatch
[BATTLE] re-attack: GET /api/orders/ord_B7  Cookie: sess_alice
         → 403  {"error":"forbidden"}
[BATTLE] control:   GET /api/orders/ord_A1  Cookie: sess_alice
         → 200  (Alice still reads her own order)
[GATE]  exploitable_after = FALSE  AND  control_ok = TRUE
[TESTS] vitest: 41 passed, 0 failed   |   build: next build OK
[SHIP]  ship-gate PASSED → draft PR #128 opened
[NOTE]  propose-and-approve: awaiting human merge. outcome (accepted? held?) tracked.

05 A clean, reviewable pull request opens

Draft PR #128 fix/orders-owner-scope +6 −3
fix(orders): enforce owner_id on GET /api/orders/[id]
survived re-attack · 200 → 403
control passed · owner still reads her own order
vitest 41 passed · next build OK
ILLUSTRATIVE EXAMPLE · NUMBERS DEPICT THE FLOW, NOT A BENCHMARK

10 GET STARTED

See what's actually wrong in your AI-built app — and what we can prove.

Comprehensive coverage — and for the serious risks, we prove it or we don't claim it.

Point us at one of your apps and we'll run VulX — comprehensive coverage across the app, with the dangerous findings (like a stranger reading your users' private data) proven by safely running the real exploit, and a fix we've proven won't break the app. You'll see the proof — the actual request and the data it shouldn't have returned — and get a pull request to review. Talk to us when a breach is the thing that could end your business.

PROVEN IN A SANDBOX · PROPOSE-AND-APPROVE · YOU MERGE.