Finding things
Static analysis
semgrep across thirteen rule packs, with a second engine added where a second engine genuinely sees more.
The engines
semgrep with the default, OWASP top ten, secrets, language and injection packs, on the languages actually present in the checkout. gosec is added for Go, where it analyzes a whole package rather than a file at a time, and bandit for Python as corroboration. Where two engines report the same line the finding says so and its confidence rises; where only the deeper engine saw it, the finding says that too.
A fidelity pass
Findings are read back in their context before anybody sees them. A value cast to an integer before output cannot carry markup, a header sent earlier changes what a later call does, an input drawn from a fixed list is not user input. Each verdict carries the sentence that justifies it, so a person can disagree with the reasoning rather than just the answer.
Rules that report a pattern
Audit grade rules exist to say "somebody should look at this", not "this is a bug". Those are marked, and can be set aside as a group rather than one exception at a time.
Two classes the public packs miss
Checked against an independent scanner on the same estate: twenty four weakness classes against a hundred and eighty rules here, twenty two of them covered and several better. The two that were not are shipped now, as rules of this product's own that are always on, because a weakness does not become less real when a rule registry is unreachable. Cross site scripting in the browser: taint mode, eight sources on the URL, six sinks that parse what they are given as HTML, nine sanitizers that are actually sanitizers, measured at five of five vulnerable shapes found and none of six safe lookalikes touched. And open redirect, for JavaScript and Python, where a value counts as handled if it appears inside an if that tested that same value, because a check is not a transformation and a sanitizer pattern will never match an allowlist guard.
JavaScript inside a page
semgrep parses HTML and it parses JavaScript, and not one inside the other, so a cross site scripting bug in a script block on a page was invisible while the same bug in a module was found. That is backwards, because a page is where this kind of code usually lives. Each block is pulled out and read as JavaScript and the finding is put back on the line of the page somebody would open. Blocks with a src attribute are skipped because that file is scanned on its own, and blocks that are not JavaScript at all are skipped rather than fed to a parser that would only produce noise.
What it does not do
Free semgrep reads one file at a time. A tainted value crossing a function boundary into another file is invisible to it, and no amount of rule tuning changes that. gosec closes this for Go. For Java, PHP and Ruby it is open, and it is the clearest gap in the product.
Every feature page carries one of those. The comparison page scores the same ground against five products people pay for, including the rows that go against us.