Automated
security testing
for web applications

ASTWA checks web apps built with AI tools for the leak they most often ship with: one user reading or changing another user's data. Give it the app's source and it boots a private copy, signs in as real test users, tries their doors, and shows you exactly what the app gave back.

The journey of one scan

Most security tools test what they are given. An unprepared app gives them nothing. ASTWA starts from the source and builds the rest.

  • No accounts, no specs
  • Access rules hide in the code
  • A 200 is not an answer

1 IntakeThe archive or repository becomes one fixed snapshot.

2 UnderstandThe source is read: tables, policies, sign-up rules.

3 GatewayA sealed gateway stands between the test users and the app.

4 Sealed bootThe app boots in its own space with its own database.

5 Schema checkThe database is checked before any test runs.

6 IdentitiesReal test users are created for this scan.

7 ProbesEach user knocks on the other's doors.

8 EvidenceFindings are judged on the data the app returned, never on a status code.

9 Fix checkA supplied fix counts only when the attack stops and the owner still gets in.

10 ReportWhat was tested, what was found, and what could not be checked.

Start with the source

Upload a zip or paste a public GitHub link. ASTWA fixes the source to one snapshot and takes it from there.

Drop your app's source here

A .zip, .tar, .tar.gz or .tgz archive

Weakness classes Leave all unticked to run every check that only reads: CWE-639 (one user reading another user's data) and CWE-862 (reading data without signing in, or without the role it needs). CWE-915 (changing a field you should not be able to change) runs only when ticked, because it writes test data to your app's database.

No credentials, .env files or login scripts needed.

Questions

What does ASTWA need from me?

An archive, a public GitHub repository or a registered snapshot. No passwords, no login scripts. No credentials, .env files or login scripts are needed.

How does a scan work?

You hand over the source. ASTWA builds a sealed copy: the app boots in its own space with its own database, and the database is checked before any test runs. Two test users then knock on each other's doors: real users created for this scan, checked for whether one can read or change what belongs to the other. You get the evidence: what was tested, the data each finding rests on, and a plain list of what could not be checked. A scan has 10 stages, from source to report, and takes about two to three minutes.

Why does an AI-built app need this?

AI app builders produce working apps quickly. Checking whether one user can read another user's data needs a running copy, real users, real records and the app's access rules. None of that comes with the code. Generated apps arrive without test accounts, login scripts or API documentation, and who may read which row lives in migrations and row-level security policies, not in a document anyone wrote.

Which apps and weaknesses are covered?

Apps made with React and Supabase: React, Vite, Supabase Auth, PostgreSQL, PostgREST and row-level security. Weakness classes in scope: CWE-639 access to another user's records, CWE-862 missing authorization, CWE-915 mass assignment.

Why not just check status codes?

An HTTP 200 proves nothing. A status code cannot tell a leak from a correct reply; only the data the app returned can. When the owner, another user and an anonymous visitor all ask for the owner's record, both 200s look the same. Only the returned rows show that the other user received the owner's record. Findings are judged on that data.

Who are the test users?

Tests run as real users created for the scan: an owner, another ordinary user, and an anonymous visitor with no session. Setup or service-role keys never stand in for them. Setup credentials prepare the sealed copy; they are never used as a tested user, and no credential appears in a report.

What does each status mean?

Every status means one thing, and a gap is never shown as clean. A test that was unsupported or could not finish is reported as such, never as “no finding”. A failed boot is not a result. “No finding” needs a valid fixture and a successful, complete check by the authorized user first.

How is a fix checked?

From both sides: a fix passes only when unauthorized access stops and legitimate use still works. Blocking everyone is a failed fix. Static scanner results are shown in their own section and never change the runtime outcome.

Can I scan a private repository?

Public github.com repositories only. Private repositories are not supported yet. The source is fixed at one commit, and the scanned app is never contacted by address.

How many scans can run?

One scan runs at a time; up to 20 can wait. While yours runs, the scan page offers a small game.