Zolt PR Review traces each change in a pull request from source to sink, decides whether it is exploitable, and posts the finding, the path, a confidence score and the patch as one comment. Nothing else.
Security issue · high · 95% confidenceResolved · path from req.query.filename to path.join is closed
Path traversal in invoice export.req.query.filename flows into path.join without validation, so a name containing ../ writes the PDF outside the upload directory.
Path traversal in invoice export.req.query.filename reaches path.join unvalidated, so ../ writes PDFs anywhere on disk.
The summary, then the lines"2 issues introduced by this change", each commented inline on the exact lines with severity and confidence.
src/routes/invoices.js · line 14
zolt-securitybot3 days ago
High· 70% confidence
Missing invoice lookup in export endpoint. The route uses invoice.id but never fetches the invoice, so nothing checks who may export which invoice.
FixLook the invoice up by id, return 403 unless invoice.user_id === req.user.sub, then sanitise the filename.AgentIn src/routes/invoices.js around line 14, fix this…copy
ReplyResolve conversation
Severity, confidence, and a promptEvery finding carries a confidence score for the exploitability call, a suggested fix, and a ready-made prompt for a coding agent.
One click to commit the fixThe fix is a suggestion on the PR. Apply it, name the commit, and it lands on the branch without leaving the thread.
01 / what it catches
The bugs that become incidents
Not lint. Not style. The classes of bug that show up in breach reports, checked against the change and everything it can reach.
Broken authorisation
Object references, tenant boundaries, role checks that a diff quietly removes.
IDOR · CWE-639 · CWE-284
Injection
User input that reaches a query, a shell, a template or a deserialiser.
SQLi · SSTI · command injection
Auth & sessions
Token comparison, JWT handling, password reset and session fixation.
timing leak · alg=none
Secrets in the diff
Keys and tokens, validated live against the provider before you are alerted.
AWS · Stripe · GitHub
Reachable dependencies
Only the CVEs whose vulnerable function your code actually calls.
SCA with reachability
Logic & races
Double-spend, coupon reuse, TOCTOU in the flows your tests never covered.
race · TOCTOU · replay
02 / it learns from you
Tell it once. It remembers.
A finding that matters in a payments service is noise in an internal health check. When you mark something accepted risk or not exploitable here, Zolt stores the decision with the repository and applies it to every review after.
Unhandled exception details are returned to the caller. Reachable only from the internal network according to the route table.
Accepted risk: stack trace on /internal/health
Saved to .zolt/decisions.md: internal-only routes may return verbose errors. Applies to this repository from now on.
Next pull request · #4910 comments posted · 1 finding suppressed— matches your decision on #482
Where a Critical goes · acme/api
Slack · visibility
Linear · tracking
Jira · tracking
#security-alertsZolt · Critical on acme/api #482 · report export not scoped to organisation · path + patch attached · merge blocked
SEC-218 · Urgent · assigned to priya-acmeScope report lookups by org (from Zolt finding #482-1). Closes when the finding closes.
APPSEC-1042 · Highest · Security backlogIDOR in report export · attack path and patch in description · linked to PR #482.
03 / where findings go
Send findings to the tools that already own the work
Comments in the PR for the author; a message in Slack for the team; a ticket in Linear or Jira for the tracker. Choose per repository, and the ticket closes when the finding does.
04 / security review vs code review
A code reviewer will still let the authorisation bug through
General AI reviewers are good at what they do. Exploitability is a different job, and it needs a reviewer that thinks about the attacker rather than the author.
A security reviewer
■Follows data from the request to the sink across files, not just the diff
■Asks whether the change is exploitable, and shows the path
■Reports by impact: what an attacker gets, from where
■Attaches the path, a confidence score and the patch
■Quiet when there is nothing to prove
A general code reviewer
□Reads the diff and comments on what it sees
□Style, naming, structure, the occasional "consider validating"
□Security remarks mixed in with everything else
□Suggests, never traces
□Something on almost every PR
05 / merge gates
Decide once what blocks a merge. Zolt applies it to every PR.
Severity and confidence thresholds per repository, kept in a file you own. Change a setting on the left and watch the check on the right.
Gate settings · acme/api
Block on critical
Block on high
Block on medium
Block on leaked secrets
Minimum confidence to blockFindings under this confidence are still posted, but never block a merge.