Status: Early-stage, independently developed. Outputs are heuristic guesses, not verified findings — read the linked commit yourself before trusting any result.
Scans a repository's recent commit history for commits that look like an undisclosed ("silent") security fix: a diff that is shaped like a defensive patch (added authorization/validation/sanitization, removed a dangerous sink), paired with a commit message that does not say so.
This tool does not find vulnerabilities. It produces a short, ranked list of commits worth a human researcher's attention. See METHODOLOGY.md for the technique, its limits, and why each signal is weighted the way it is.
Many maintainers fix security-relevant bugs quietly — no CVE request, no "security" in the commit message, sometimes no linked pull request at all. A researcher who catches one of these early can disclose responsibly before the issue becomes public knowledge (e.g. once a CVE is eventually filed weeks later); a defender can patch ahead of the public advisory. This tool narrows a commit history down to a short list grounded in the commit's own message and diff — verification and judgment stay a human's job.
It is designed to feed its sibling tool, regression-hunter: once a candidate here is manually confirmed as a real (if undisclosed) security fix, regression-hunter's same "sibling file" search logic can be pointed at it to check whether the same missing check exists elsewhere in the codebase.
pip install -r requirements.txtOptional: set GITHUB_TOKEN to raise the GitHub API rate limit from
60/hour to 5000/hour — this tool makes roughly 2 requests per commit
scanned (one for the diff, one for the associated-PR check), so anything
past ~25 commits unauthenticated will hit the limit.
python3 -m silent_patch_finder scan <owner>/<repo> [options]Options:
--since DATE ISO-8601 date; only consider commits after this
--limit N max commits to fetch (default: 25, unauthenticated rate-limit-safe)
--min-confidence {high,medium,low} only show candidates at or above this tier
--json print structured JSON instead of Markdown
--out FILE write the report here instead of stdout
--cache-dir DIR cache raw per-commit API responses to avoid re-fetching
--skip-pr-lookup halve API usage; loses the no_associated_pr signal
Example:
python3 -m silent_patch_finder scan portainer/portainer --limit 50 --min-confidence medium| Signal | Weight | What it checks |
|---|---|---|
vague_message_defensive_diff |
3.0 | The flagship signal: diff looks defensive, message downplays or doesn't mention it — this is what "silent" means |
sensitive_path |
1.5 | Touched file path matches a security-sensitive keyword (auth, crypto, upload, deserialize, ...) |
defensive_diff_shape |
1.5 | Added lines call an authorization/validation/escaping function, or removed lines had a dangerous sink |
no_associated_pr |
1.0 | No pull request is linked to the commit — supporting signal only, never qualifies a commit alone |
small_focused_diff |
0.5 | Few files, few lines — typical of a targeted patch — supporting signal only |
A commit is only reported at all if sensitive_path or
defensive_diff_shape fired — the two "supporting" signals above add
weight but can never by themselves produce a candidate (see
METHODOLOGY.md for why that gate exists).
No model is in the loop. Every signal is a deterministic keyword/regex match against the commit's own message and diff text — every line of a report traces back to something a human can click and verify (the commit URL), same as cve-explain. There is nothing generated freely, so there is nothing to hallucinate.
That does not mean the results are accurate in the precision sense. Keyword/pattern heuristics have real, expected error in both directions:
- False positives: ordinary defensive coding that has nothing to do with a vulnerability (adding a nil-check, a normal input validator for a new feature) will often match.
- False negatives: a real silent fix phrased blandly enough, or with a diff shape this tool's keyword lists don't cover, will be missed.
Every result ships with its fired signals and a plain-text reason so a human can immediately see why it was flagged, and reject it in seconds if wrong. See METHODOLOGY.md's "Known limitations" section for specifics found while testing this tool against a real repository.
Only use this against repositories you are authorized to research, per their own security policy / responsible disclosure process. This tool only calls the public GitHub API — it never scans, exploits, or contacts any running instance of the target software. Always follow the target project's documented disclosure process for anything you decide, after manual verification, is real.