Skip to content
sentrasec
← All posts

Why we built our own scanners

Orchestrating other people's scanners is the fast path to a product and the slow path to a good one. A note on what we gave up and what we got back.

Sentrasec Engineering

The fastest way to ship an application security platform is to not write any scanners. Wrap the well-known open-source tools, normalise their output into a common schema, put a dashboard on top, and you have something demonstrable in a few weeks.

We tried that first. Here is why we stopped.

The normalisation tax

Every wrapped scanner reports in its own shape. One emits a line number, another a byte offset, a third a function name. Severities disagree: what one tool calls high, another calls medium, and neither is wrong because they are measuring different things.

The wrapper's job is to reconcile all of that into one schema. That reconciliation is lossy in a way that matters: the information you throw away to fit a common shape is usually the information that would have told you whether the finding is real.

You end up with a schema that is the intersection of what every tool provides, not the union. The richest signal any individual scanner produced does not survive.

Deduplication needs semantics

Three scanners find "the same" SQL injection. Are they the same finding?

Answering that requires knowing whether they refer to the same code path, not the same line, the same path. A wrapper sees three records with different location formats and has to guess, usually with fuzzy matching on file and line proximity. It gets it wrong in both directions: merging distinct issues, and reporting one issue three times.

When the scanners share a common understanding of the code they analysed, this is not a heuristic. Two detections on the same path are the same finding, by construction.

You cannot fix what you do not own

A false positive in a wrapped tool is somebody else's bug. You can suppress it, add a filter, maintain an ever-growing exclusion list, but you cannot fix it. Over time the filter list becomes its own liability, encoding workarounds nobody remembers the reason for.

When the detection is yours, a false positive is a bug report with a fix on the other end.

What it cost

Real time. Building analysis that understands code structurally is substantially more work than shelling out to a tool that already does it. The same is true of dependency resolution across ecosystems, of infrastructure definitions across six formats, of dynamic testing.

We think it bought three things worth having:

  • One finding model. Every scanner produces the same structure, so deduplication and correlation are exact rather than approximate.
  • One severity scale. Comparing a secrets finding against a dependency vulnerability is meaningful because both were scored by the same system.
  • A single pass. All applicable scanners run together over one analysis of your code, rather than each redoing the work.

The part that actually mattered

The deciding argument was not any of the above. It was the knowledge graph.

Connecting a finding to the weakness class beneath it, the OWASP category above it, and the fixes known to resolve it requires the finding to carry structure the graph can attach to. A normalised record scraped from another tool's output does not have that structure: the relationships were discarded before we ever saw it.

Owning detection end to end is what makes the reasoning layer possible. That is the whole reason.