Catch SQL injection and leaked secrets before they merge
Security review that only happens at release is too late. Here's how to catch the OWASP Top 10 vulnerability classes on every pull request — with evidence, a CWE, and a fix you approve.
Most security problems don't ship because someone was careless. They ship because the review that would have caught them happened at the wrong time — or didn't happen at all. A pen test runs once a quarter. A scanner runs on main after merge. By then the vulnerable line is already in the history, already deployed, already a thing you have to roll back instead of a thing you quietly fix in review.
The fix is to move the check to the one moment every change already passes through: the pull request.
Why the pull request is the right place
Every other quality gate in a healthy repo lives at the PR: tests run, types check, lint fires, a human reviews. Security is the odd one out — it's bolted on later, somewhere else, on a different cadence. So it's the gate developers feel least, and the one most easily skipped under a deadline.
Put the security check on the PR and it inherits everything that makes the other gates work. It's visible (a red check, right there). It's timely (the author still has the context in their head). And it's cheap to act on (one flagged line, not a 40-page quarterly report nobody reads to the end).
What's worth catching automatically
You don't need a tool to find exotic, novel exploits — those need humans. You need a tool to reliably catch the boring, high-impact mistakes that account for most real incidents. The OWASP Top 10 classes, essentially:
- Hardcoded secrets — a live API key or AWS credential committed in plaintext (CWE-798).
- SQL injection — user input concatenated into a query (CWE-89).
- Command injection — a shell command built from request data (CWE-78).
- Cross-site scripting — unescaped user HTML rendered to the page (CWE-79).
- Broken authorization — an endpoint missing an ownership check (CWE-862).
- SSRF — an outbound URL taken straight from the request body (CWE-918).
- Insecure deserialization, weak crypto, disabled TLS verification, path traversal — the rest of the usual suspects.
None of these are clever. All of them ship constantly. A check that catches them on the PR removes a whole category of "how did that get to production" from your week.
The trap: a scanner that cries wolf
The reason teams turn security scanners off is noise. A tool that flags 200 "issues," most of them false positives or unreachable, trains everyone to ignore it — and then it misses the one that mattered, because nobody's reading the alerts anymore. Signal is the entire game.
Two things keep the signal high. First, only review what changed — read the diff, not the whole repo, so you're not re-litigating code that was already there. Second, bring evidence: every finding should come with the exact file and line, the CWE identifier, the concrete risk, and a recommended fix. A finding you can verify in five seconds gets fixed. A vague "potential issue" gets dismissed.
This is the same grounding discipline that keeps auto-drafted docs honest — constrain the output to what's actually in the diff, and attach proof to every claim. We go deep on that idea in the pillar guide, Documentation that updates itself.
Don't just flag it — draft the fix
Flagging a vulnerability is half a job. The author still has to figure out the safe pattern, write it, and re-run the check. The better move: for issues with a known-safe fix, open the fix as its own pull request — the parameterized query, the bumped dependency, the escaped output — and let the author review and merge it. The work is pre-done; the human still decides. Nothing merges automatically.
That last part matters. Automated security tooling earns trust by being an assistant, not an authority. It assists, you decide.
Where this fits — and where it doesn't
Be honest about scope, because over-claiming is how security tools lose credibility. PR-time scanning is a catch for common, high-impact mistakes before they merge. It is not a penetration test, not a guarantee of complete coverage, and not a replacement for a security team or a formal audit. It's the seatbelt, not the crash investigation — and most teams are driving without one.
Try it on one repo
This is exactly what docs-keeper does on the security side: it reviews every pull request for these vulnerability classes, posts each finding with its file, line, CWE, and fix, and opens a fix PR you approve. It runs inside the GitHub flow your team already uses — no new dashboard to babysit — and it never merges anything on its own.
See the full breakdown of what it catches on the security scanning page, or just turn it on:
Keep reading
Documentation that updates itself: a practical guide to keeping docs in sync with code
Docs rot because nothing connects them to your code. This is the complete guide to closing that gap — the failure modes, the four levels of automation, and how to make docs a side effect of merging.
The real cost of stale documentation (it's not what you think)
Out-of-date docs don't just annoy people — they quietly tax onboarding, support, and trust. Here's how to actually measure the cost, and why the damage compounds.
Why your README always lies (and how to stop it)
Docs don't rot because developers are lazy. They rot because nothing connects them to the code. Here's the structural fix — and why 'just be disciplined' never works.
