acme-payments/core / runs / run.a7f29b1
scan complete CF

Run run.a7f29b1 · acme-payments/core

apr 18 · 11:42 UTC 3m 14s elapsed portable ensemble · 3 + 1 cost $3.81 sigstore signed
14
total
2
critical
5
high
7
medium
6
confirmed
8
candidate
Filter State: confirmed × Severity Reachability CWE Specialist Evidence rank + Add filter
Sort severity ↓ group by file
Session token not invalidated on logout path
src/auth/session.py:42–68 · validate_token()
critical reachable confirmed internet-facing handles-pii
1 3 5
CWE-416
SSRF via user-supplied URL in webhook dispatcher
src/integrations/webhooks.ts:114 · dispatchWebhook()
critical reachable confirmed
1 3 4
CWE-918
Missing authorisation check on /admin/users endpoint
src/api/admin/users.py:28 · list_users()
high reachable confirmed spring-security-agent
3 4
CWE-862
Insecure deserialisation of pickle payload from Redis
src/workers/task_loader.py:67 · load_task()
high potentially reachable candidate
3 5
CWE-502
SQL injection via unsanitised order-by parameter
src/api/reports/query.py:92 · build_query()
high reachable confirmed
1 3
CWE-89
Weak random used for password reset tokens
src/auth/reset.py:38 · generate_reset_token()
high reachable confirmed crypto-agent
3 4 5
CWE-338
Prototype pollution via Object.assign on user input
src/utils/merge.ts:19 · deepMerge()
medium potentially reachable candidate
3
CWE-1321
Path traversal in file upload handler
src/api/uploads/handler.py:54 · save_upload()
medium potentially reachable candidate
3 5
CWE-22
XSS via unescaped merge field in email template
src/email/render.py:46 · render_template()
medium potentially reachable candidate
3
CWE-79
Timing-unsafe string compare on HMAC verification
src/auth/hmac.py:22 · verify_sig()
medium unreachable candidate
3
CWE-208
Critical Reachable Confirmed f_03b1 · CWE-416 · Use-After-Free

Session token not invalidated on logout path

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

Evidence stack · 3 labelled

1
CPG reachability path
14 nodes · source request.cookies["sid"] → sink session.user_id
cpg-path.json
3
Ensemble + held-out judge
4 / 4 families agree · judge grade A · collapse score 0.31
votes.json
5
Validator · cwe-416
fine-tuned local MLX · 98.1% confidence · 24ms
validator.log

Source · src/auth/session.py

src/auth/session.py · validate_tokenpy · 68 lines
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() # ← free
48 audit_log.record(session.user_id, "logout")
64 return session.user_id # ← use-after-free
65

Ensemble · 4 families · judge = Kimi

FAM / ANTHROPICYES
claude-opus-4-7
confidence 0.94
FAM / OPENAIYES
gpt-5
confidence 0.89
FAM / GOOGLEYES
gemini-3-pro
confidence 0.91
JUDGE / MOONSHOTGRADE A
kimi-k2
grade: valid · consistent · schema-ok
collapse detector: 0.31 (below 0.85 threshold) · rationale cosine: 0.34 / 0.41 / 0.29

Provenance triple · sigstore-signed

prompt_hashsha256:7c1b40e9a8f2d631…ac48
generatoranthropic / claude-opus-4-7 · 2026-03-15
judgemoonshot / kimi-k2 · 2026-02-09
containersha256:4a9e1c…3f72 · ghcr.io/cve-hunter:0.4.2
signatureruns/a7f29b1/provenance.sigsigstore

Fix guidance · patchable

Reorder: capture session.user_id into a local before calling session.delete(). Return the local, not the freed object.
adds test: assert token revocation propagates to Redis before 200 response · suggested diff: +4 −2 LOC
scan complete · 3m 14s 14 findings · 6 confirmed cost: $3.81 / $50.00 budget cache hit: 62% schema v1 · sarif 2.1 sigstore: ok