August 2026 – Tech Update

Table of Contents

A public API, and the bugs we found auditing ourselves

This month the API that’s been running internally for months went into testing with a real public surface: keys, scopes, signed webhooks, metered billing. Building it forced us to look hard at our own product, and that look turned up a cluster of real security defects, all now closed. On the detection side, false-positive noise fell for another consecutive quarter and nine new vulnerability classes went live in the scanner.

The API

Twelve routes cover the full scan lifecycle. You can create a scan from a verified on-chain contract or from uploaded .sol / ZIP source, poll status, read findings, and download results as SARIF 2.1.0 for your existing tooling.

Access runs on team-scoped, revocable API keys, hashed at rest, each carrying scopes for a specific capability rather than blanket access. Entitlement checks — do you have the scope, do you have the quota — are enforced atomically, and every refusal has a documented meaning: no generic 400s papering over what actually went wrong.

Results reach your systems without polling. Register a webhook endpoint and deliveries arrive signed, with secret rotation across an overlap window so you can roll credentials without downtime. Every endpoint gets its own delivery history and metrics, backed by a bounded outbox sweep rather than an unbounded retry queue.

The docs are generated from the API surface and pinned to it, so they can’t quietly drift out of sync with what’s actually deployed.

On the console side, sign-up no longer requires a GitHub account, and there are now self-service screens for keys, scopes, usage, webhooks, and credits — the account-management work that used to mean emailing us.

What we found auditing ourselves

Before rolling the API out, we audited the product it sits in front of. That process surfaced six issues worth being direct about:

A live GitHub credential was sitting in the session token and coming back on user reads. It’s now omitted at the database client itself, so no call site (present or future) can leak it.

Report tokens authorized writes to any tenant’s scan, not just the one they were issued for. They’re now bound to a single scan, with replay detection on top.

Issue-status changes weren’t scoped to tenancy.

The public upload path accepted hostile archives: path traversal, symlinks, decompression bombs. All three are now rejected outright, with entry-count and size caps enforced on every upload.

Our Sentry integration was receiving default PII. It’s now scrubbed at the integration layer, and we built a leak harness in CI to prove it stays scrubbed rather than take it on faith.

The console had shipped with 25 open dependency advisories, eleven of which reached the browser bundle, including the library holding the session token. That’s now zero, with a CI gate that fails the build if it happens again.

We’re publishing all six because a security vendor that only talks about the bugs it finds in other people’s code isn’t being straight with you about how software actually gets built.

Nine new vulnerability classes

Two of the nine reproduce the root cause of vulnerabilities that have already cost real protocols real money: first-depositor share inflation, the donation attack behind several ERC-4626 vault losses, and the rounding-favors-the-user-against-the-flow-role pattern behind the Balancer v2 stable-pool exploits.

The other seven: decimals() count used where a base-10 unit conversion was actually meant; missing signature-replay validation; a denial-of-service condition from non-atomic signed-batch processing; missing or spoofable slippage protection on an external swap, and the same gap in that swap’s self-token sibling; privileged transfers to a recipient that’s never validated; and authority transfer for access control done in a single step, with no timelock or acceptance step to catch a mistake.

Noise down another 25%

Across 606 real audited protocols in our benchmark corpus, findings that matched no ground-truth marker fell from 18,269 to 13,788. On SmartBugs, unmatched findings fell from 1,071 to 924, matched markers rose from 213 to 215, and misses dropped from 9 to 7.

Separately, we found that 174 of the 180 CRITICAL findings our access-control detector had produced across the whole corpus — 97% of them — were false criticals, all traced to one over-broad pattern that was scoring ordinary accounting writes as governance takeovers. That pattern is fixed now, but it’s a useful reminder that a single bad rule can dominate a severity tier’s error rate.

Reliability

A monorepo scan produced an 8 MB SARIF report that blew past the database response limit on the completion write, the scan finished but couldn’t record that it had. Scans now run in isolated subprocesses, which we proved byte-identical to the old in-process output before cutting over, with bounded admission that sheds excess load with a 429 instead of queuing indefinitely, and that hard-kills a scan that’s wedged. A scan can no longer be left in a RUNNING state forever.

And, for what it’s worth on the “small things break big systems” front: a one-line contract – uint256 private salt = block.timestamp; was enough to kill an entire scan at the report boundary. Also fixed.

Next month

We’re closing the recall gap our coverage instrumentation exposed, working precision on the two highest-volume detector families still generating noise, promoting coverage attribution from a report you have to go read into an actual CI gate, and taking the API from internal testing to live with customers.

Share:

More Posts

Scan your project now for free

Tell us your security needs