For teams buried in AI security findings

Exploit-test every
security finding.

Alethix replays each finding from your AI reviewer or scanner against a disposable copy of your app. Only the bugs it can prove reach your queue.

~/ledger 8 findings, 2 proven

$ alethix verify --repo ./ledger --findings review.sarif --fix

alethix — verifying 8 finding(s) against ledger in a local Docker sandbox

· booting a disposable copy of ledger …

· ready — replaying each finding as an independent, read-only check

· 0-0-broken-object-level-authz: exploitable

· 0-1-missing-function-level-authz: exploitable

· 0-2-broken-object-level-authz: reachable

· 0-3-missing-authorization: not-an-issue

· 0-4-missing-security-headers: hardening

alethix — 8 finding(s) checked

2 exploitable 1 reachable, not proven 4 hardening only 1 not an issue

EXPLOITABLE (2)

- Invoice detail endpoint returns an invoice to any authenticated user … [app.py:134]

alice received bob's canary data across an auth boundary

- Admin users listing endpoint has no role check … [app.py:146]

alice received bob's canary data across an auth boundary

✓ fix verified Invoice detail endpoint returns an invoice … [app.py]

re-ran the same check: request as alice was denied (403); access control held

✓ fix verified Admin users listing endpoint has no role check … [app.py]

re-ran the same check: request as alice was denied (403); access control held

Real CLI output, trimmed to fit. Ledger is our demo invoicing API with two planted access-control bugs. The eight findings came from a claude-code-security-review export.

Working with teams at

  • Makonis
  • Zentact Systems

Finding bugs got cheap. Proving them didn’t.

AI reviewers and scanners flag issues faster than any team can check them. Much of the queue is hardening advice, unreachable code, or a guess labeled critical.

So a senior engineer reads every one by hand, or the queue gets ignored. Both are expensive.

“the mind-numbing AI slop”
Daniel Stenberg, on why curl ended its bug bounty, January 2026
review queue unverified
  • criticalSQL injection in search query builder' OR 1=1 --
  • highInvoice endpoint skips the tenant checkGET /invoices/2002
  • mediumNo rate limiting on loginPOST /login ×500
  • criticalSSRF in webhook URL fetchhttp://169.254.169.254
  • highReflected XSS in comment preview<script>
  • mediumStack traces may leak in error handler500 Traceback
  • highPath traversal in file download../../etc/passwd
  • criticalJWT signature not verified"alg": "none"
  • highAdmin route lacks a role checkGET /admin/users
  • mediumPrototype pollution in deep merge__proto__
  • lowMissing X-Content-Type-Options headernosniff
  • mediumOpen redirect after sign-in?next=//evil.example
Everything sounds urgent. Nothing has been run.

We plant a canary. Then we replay the bug.

If the canary reaches the wrong user, the bug is real. If it doesn’t, you get the evidence for that too.

01 ingest

// review.sarif, result 1 of 8
{
  "ruleId": "broken-object-level-authz",
  "level": "error",
  "message": { "text": "Invoice detail endpoint
     returns an invoice to any
     authenticated user …" },
  "locations": [{ …
    "uri": "app.py",
    "startLine": 134 }]
}

8 findings, one shape

  • 0-0 broken-object-level-authz app.py:134
  • 0-1 missing-function-level-authz app.py:146
  • 0-2 broken-object-level-authz app.py:113
  • 0-3 missing-authorization app.py:121
  • 0-4 missing-security-headers app.py:85
  • 0-5 insecure-transport app.py:85
  • 0-6 missing-rate-limiting app.py:98
  • 0-7 verbose-errors app.py:85

$ docker compose up (a throwaway project name)

· booting a disposable copy of ledger …

· GET /healthz 200 ready

ledger, disposable copy

tenant acme

a alice tok-alice

invoice 1001 acme website redesign

tenant globex

b bob tok-bob

invoice 2002 globex retainer LEDGER-canary-9b1f4c2a7d

Only bob should ever see the canary. If a request made as alice returns it, a tenant boundary was crossed.

aaliceacme
GET /api/invoices/2002 200 LEDGER-canary-9b1f…
ledgerinvoice 2002 is bob’s
→ GET /api/invoices/2002
  Authorization: Bearer tok-alice
← 200 {"id": "2002", "tenant": "globex", "amount": 9900.0,
       "memo": "globex retainer LEDGER-canary-9b1f4c2a7d"}
EXPLOITABLE alice received bob’s canary data across an auth boundary
NOT AN ISSUE GET /api/invoices/2002/pdf as alice was denied (403); access control held
@@ app.py  GET /api/invoices/<id> @@
     inv = data["invoices"].get(inv_id)
     if not inv:
         return self._send(404, {"error": "no such invoice"})
-    # BUG: returns the invoice to any authenticated caller
+    # Authorization: invoice must belong to the caller's tenant.
+    if inv["tenant"] != who["tenant"]:
+        return self._send(403, {"error": "forbidden"})
     return self._send(200, inv)
aaliceacme
GET /api/invoices/2002 403 forbidden
ledgerpatched copy
✓ FIX VERIFIED re-ran the same check: request as alice was denied (403); access control held

Every finding leaves with a verdict.

Each bucket carries the evidence that put the finding there. A check that can’t run is reported as errored, never as all clear.

Exploitable

2

Reproduced, with real impact.

  • Invoice detail returns any tenant’s invoice app.py:134
  • Admin user list has no role check app.py:146

alice received bob’s canary data across an auth boundary

SARIF error, fails CI

Reachable

1

Not proven. The input reaches the code, no impact shown.

  • Invoice list may leak other tenants app.py:113

no bob data seen in alice’s response (status 200)

SARIF warning

Hardening only

4

Defense in depth. Not a live bug.

  • X-Content-Type-Options missing app.py:85
  • HTTPS not enforced app.py:85
  • No rate limiting app.py:98
  • Stack traces may leak app.py:85

no code path returns a stack trace, so there is nothing to reproduce

SARIF note

Not an issue

1

The check ran and the app held.

  • PDF download may expose other tenants app.py:121

request as alice was denied (403); access control held

SARIF none, safe to close

Lives in your terminal and your CI.

No dashboard to log into. Point it at a repo and the findings file you already have.

$ alethix verify --repo . --findings review.sarif --exit-code

alethix — 8 finding(s) checked

2 exploitable 1 reachable, not proven 4 hardening only 1 not an issue

EXPLOITABLE (2)

- Invoice detail endpoint returns an invoice … [app.py:134]

- Admin users listing endpoint has no role check … [app.py:146]

$ echo $?

1 # the build fails on proof, not on noise

SARIF in, SARIF out
Verdicts go back as SARIF levels, so they land in the code-scanning views you already use.
An exit code for CI
--exit-code returns 1 only when something is exploitable.
Same answer every run
Model answers are cached, so a rerun is instant and identical.
No dependencies
Python standard library, plus Docker for the sandbox.
  • Static scannersSARIF
  • AI code reviewSARIF
  • AI pentest agentsSARIF
  • Bug bounty reportsplain text

Alethix

  • exploitable
  • reachable
  • hardening
  • not an issue

We don’t find bugs. We check the ones you already have.

Scanners, AI reviewers and AI pentesters all write findings. Alethix is the independent check that runs them, whichever tool they came from.

A model proposes each check and each patch. It never decides the verdict: a deterministic oracle looks for observable impact, and a person confirms.

Send us the findings you don’t trust.