cve-hunter · prototype
1 · target 2 · scan 3 · findings 4 · fix
§ Step 1 · Choose target

Which repository would you like to scan?

Pick a repo, configure the run, and we'll dispatch the pipeline. Scans are bounded: a budget cap, a time cap, and a mechanical evidence gate — nothing open-ended.

acme-payments/core
python · fastapi · postgres · 312k LOC · last scanned 2 days ago
main 2 open findings
acme-payments/webhooks
typescript · node · 42k LOC · never scanned
main new
acme-payments/admin
typescript · next · 88k LOC · last scanned 9 days ago
release/v2 4 open findings

Ensemble

Portable
3 + 1
opus-4.7, gpt-5, gemini-3, judge kimi
Fast
2 + 1
opus-4.7, gpt-5, judge kimi
Deep
5 + 2
+ local llama-3.3, qwen-3

Budget

Tight
$2.00
one-pass · sample hotspots
Standard
$5.00
400 hypotheses · full pipeline
Exhaustive
$25.00
800 hypotheses · re-judge all
§ Step 2 · Scanning

Scanning acme-payments/core

run.a7f29b1 · 0.0s elapsed · portable ensemble · cost $0.00
01Preprocessor
queued
02Hypothesis queue
queued
03Specialist swarm
queued
04Ensemble + judge
queued
05Evidence labelling
queued
06Reporter
queued
Files scanned
0
Hypotheses
0
Confirmed findings
0
Budget used
$0.00
sigstore provenance capturing in real-time press space to jump to results →
§ Step 3 · Findings · acme-payments/core

14 findings · 6 confirmed

run.a7f29b1 · 3m 14s · cost $3.81 · 62% cache · sigstore signed

evidence ranks: 1 CPG 3 ensemble 4 specialists 5 validator
14 findings
← back to findings
Critical Reachable Confirmed f_03b1 · CWE-416

Session token not invalidated on logout path

src/auth/session.py:42–68 · validate_token()

Evidence stack

1
CPG reachability
14 nodes · source → sink
3
Ensemble + judge
4/4 agree · grade A · collapse 0.31
5
Validator · cwe-416
fine-tuned MLX · 98.1% · 24ms

Ensemble votes

ANTHROPICYES 0.94
opus-4.7
OPENAIYES 0.89
gpt-5
GOOGLEYES 0.91
gemini-3
JUDGEGRADE A
kimi-k2

Source excerpt · src/auth/session.py

42def validate_token(token: str) -> Session | None:
43 # decode without verifying sig — relies on Redis presence
44 claims = jwt.unverified_decode(token)
45 session = redis.get(f"session:{claims['sid']}")
46 if not session: return None
47 session.delete() # ← memory freed here
48 audit_log.record(session.user_id, "logout")
64 return session.user_id # ← use-after-free

Fix guidance

Capture session.user_id into a local before calling session.delete(). Return the local, not the freed object. Add regression test asserting token revocation propagates to Redis before the 200 response.
suggested diff: +4 −2 LOC · 1 test added

Fix PR drafted.

Branch fix/f_03b1-session-uaf pushed. Evidence bundle attached as EVIDENCE.md.

+ user_id = session.user_id // capture before free
+ session.delete()
+ audit_log.record(user_id, "logout")
+ return user_id
- session.delete()
- return session.user_id
SPACE skip scan next ESC back