Matteo Panzeri/AI-for-security

AI-for-security · measurement first

Measuring where AI over-claims, and building the harness that proves it.

Models find vulnerabilities at scale now, so raw discovery is cheap. The hard part is validation and calibration: which findings are real, how severe they actually are, and whether a method beats a plain model call.

I work one method deeply, a class-agnostic sibling-diff / incomplete-fix detection method across CWEs on the AI and agent surface, and build the model-agnostic harness that measures it. The baseline I test against is a single naive call to a current frontier model I run; I make no claim against closed systems I cannot run.

sota_bench · SOTA-validation loop
$ sota_loop --naive --method --target authz_v1
pinned baseline ............................ ok
naive (single frontier call) .... reached site, dismissed bug
method (runtime oracle) ......... a finding secure → VULN ✓
delta: method recovered 1 finding static skepticism missed
> 4-item runtime re-run; on the full 16-item baseline the static method lost (Δ −0.167, below)
> the disclosures and the method are the substance. the measurement keeps them honest.
method − naive · runtime a finding · static: secure → runtime: VULN

The thesis

Models find candidate bugs cheaply. They do not triage them, calibrate severity, or notice where they are confidently wrong. That gap widens as models improve: someone still has to measure whether a new model is actually better, and whether a given method still earns its place.

sota_bench is an open, model-agnostic benchmark with a non-LLM scorer and a pinned baseline: one naive call to a frontier model I run (no access to closed systems like Mythos), re-scored on each release. Its first run was useful and uncomfortable: a static version of my own method did not beat that naive call. The method's value is the runtime check: on a live re-run it recovered the exact finding static skepticism had cleared. A benchmark that corrects you is doing its job.

pinned baseline · 16 items · 2026-06-03
naive recall 0.833 > method 0.667 · signed Δ −0.167  (the method lost; published as-is)
open scorer · github.com/matte1782/sota-bench ↗

The measurement, end to end

Every number is a deterministic function of labels, content-addressed so it cannot be quietly fudged, and the loop refuses to compare two runs it cannot honestly compare. That refusal is what keeps the signed delta trustworthy as models change.

  1. corpuslabeled positives and exonerated negatives, each pinned to repo@sha
  2. dataset_hashSHA-256 content address of the exact scored corpus
  3. scorer.pydeterministic, no LLM-as-judge
  4. comparability gaterefuses to diff two runs unless dataset_hash and scorer_version both match
  5. McNemar + powerunder 10 discordant pairs → UNDERPOWERED: no significance claimed
  6. signed Δmethod − naive, published as-is

A real recording of python -m sota_bench, self-hosted: every command runs on a fresh clone (stdlib only, no API key, no private corpus). It shows the published baseline (the method lost to a naive call), the ValueError the comparability gate raises on an incomparable diff, and the admission floor rejecting the n=3 decode seed. Press play, or read the same lines above without JavaScript.

Selected disclosures

High 8.5 Open WebUIServer-side request forgery via an OAuth picture claim (CWE-918): validate_url checks only the initial URL, then aiohttp follows a redirect to an internal target and returns its body through the profile image. Sole-lead; the sixth redirect sink the v0.9.5 parent fix (CVE-2026-45401) missed. CVE-2026-54008. CVE-2026-54008 High dexToken-exchange endpoint missing per-client connector ACL enforcement (CWE-285). Reporter fix-PR merged. Severity self-assessed; the advisory carries no CVSS and no CVE (master-only). GHSA-7qjx Critical 9.2 LangroidNeo4jChatAgent runs LLM-generated Cypher with no validation: prompt-to-Cypher injection on the agent surface, config-conditional RCE. The query-validation fix shipped for SQLChatAgent (CVE-2026-25879) was never carried to the Neo4j path, so read_query / write_query executed the model's Cypher directly. Found by sibling-diff from that prior fix; sole reporter, and the 0.65.5 patch extended validation to Cypher and AQL. CVE-2026-55615, CVSS v4 9.2 Critical as rated by the advisory. CVE-2026-55615 High traefikHeader-field underscore-variant identity spoofing in BasicAuth / DigestAuth / ForwardAuth: the auth middlewares treat an underscore header variant inconsistently, enabling identity spoofing / auth bypass. Incomplete-fix / cross-cohort sibling of CVE-2026-33433 + CVE-2026-39858. Sole reporter. CVE-2026-54763. CVE-2026-54763 High ouroborosUntrusted project .env (auto-loaded from the working directory) can still reach RCE via execution-routing keys omitted from the denylist. An incomplete fix of CVE-2026-47211, found by sibling-diff. Co-credited reporter (with hackkim). Fixed in ouroboros-ai 0.42.1 (keys added to _UNTRUSTED_ENV_DENYLIST + cwd auto-discovery removed). Severity self-assessed; the advisory carries no CVSS and no CVE. GHSA-jv2h High agenticmailUnauthenticated inbound mail triggers a bypassPermissions resume of the operator's Claude Code session (bridge-wake) with no sender gate, while the sibling operator-query hook authenticates the sender (CWE-306). Found by sibling-diff: the wake path omits the authentication the query path enforces. Config-conditional (headless bridge + a fresh host session + the model obeying the injected content), not a deterministic RCE primitive. Sole reporter; maintainer-published. GitHub issued CVE-2026-57495 (repo-published; pending NVD sync). Severity self-assessed; the advisory carries no CVSS. CVE-2026-57495 High trigger.devCross-tenant task replay via missing per-resource authorization on the replay endpoints (CWE-862/639): a caller could replay another tenant's task run. Found on the authorization surface by sibling-diff. Co-credited reporter (with Wernerina); maintainer-published. Severity self-assessed; the advisory carries no CVSS and no CVE. GHSA-9fq3 High 7.3 Open WebUIStored XSS via an OAuth picture claim stored as an SVG data URI (CWE-79). Patched 0.9.5. GHSA-3wgj Mod 6.3 MCP RegistryUnauthenticated SSRF bypassing the private-address allowlist via 6to4 / NAT64 (CWE-918). CVE-2026-44430. CVE-2026-44430 Mod 6.0 GitHub MCP ServerLockdown-mode RepoAccessCache singleton in HTTP mode binds every user's repo-access checks to the first authenticated user's GraphQL token: cross-user authorization confusion (CWE-284). CVE-2026-48529. Credited reporter (co-reported). Patched 1.1.2. CVE-2026-48529 Mod 5.3 KirbyContent locks disclose IDs and emails of otherwise-inaccessible users (CWE-862). CVE-2026-45334. CVE-2026-45334 Mod OutlineCross-tenant IDOR in subscription creation on private documents (CWE-639). CVE-2026-43890. Shown at the GHSA's qualitative Medium; the advisory carries no CVSS (NVD separately lists 7.7 via a GitHub-supplied vector). CVE-2026-43890 High 8.6 Google MCP ToolboxSQL injection and security-boundary bypass allowing the allowedDatasets scope to be escaped (CWE-89, CWE-863). CVE-2026-15829, CVSS v4 8.6 High, assigned by Google as CNA, which credits 'Matteo Panzeri (Universita di Pavia), GitHub @matte1782' as finder. The CVE record scopes itself to the prebuilt bigquery-forecast tool; the merged fix, googleapis/mcp-toolbox PR #3324, covers both the forecast and analyze-contribution tools. CVE-2026-15829 Low Apache AirflowPer-Dag read authorization bypass (CWE-863): a user authorized to read one Dag could disclose the source of other Dags co-located in the same source file, because GET /api/v2/dagSources/{dag_id} and the equivalent UI view returned the whole file without redacting Dags the caller could not read. CVE-2026-49296, assigned by the Apache Software Foundation, whose announcement rates it Low and credits 'Matteo Panzeri (Universita di Pavia), GitHub @matte1782' as finder alongside Jarek Potiuk as remediation developer. Apache's own CNA record carries no CVSS vector; a CISA-ADP enrichment separately adds CVSS v3.1 6.5 Medium. Fixed in 3.3.0. CVE-2026-49296

CVSS severities, as the official advisory rates them. Additional findings are in private coordination and are not listed until disclosed.

Open tooling & method

benchmark · scorer · loop

sota_bench

A model-agnostic benchmark for the validation/calibration layer: a labeled positive/negative corpus, a deterministic non-LLM scorer (recall · precision · FP-rate · both-ways CVSS calibration), and the SOTA-validation delta loop. Open (Apache-2.0) and runnable: the scorer reproduces the −0.167 delta.

github.com/matte1782/sota-bench ↗
named specialization

Incomplete-fix siblings, class-agnostic

A security patch routinely closes one sink, route, or resource while a sibling path to the same dangerous action survives. The detection method is a sibling-diff from a merged fix, verified by a non-fabricatable runtime oracle, and it is class-agnostic: the same sweep produced findings across SSRF, authorization, auth-bypass, and XSS. Flagship: CVE-2026-54008, a sole-lead HIGH SSRF in open-webui where a five-reporter parent fix patched five redirect sinks and the method found the sixth.

writeup ↓
active research · a second class

Decode-completeness

A decoder that silently drops a value-reducing field (a debt leg, a scaling exponent, an authorization-relevant field) so a naive read reaches the site and rules the bug out. Early, honest signal across 3 public findings (a DeFi accountant, a Solana paymaster, an oracle): in this retrospective test the method caught the subtle ones a naive call missed, while a deliberately-included eyeball-able control shows where it does not. n=3 · underpowered · recall-only · not yet a calibrated rate.

growing toward a measured rate ↗

Writing

2026 · 07 I scored my own bug-hunting protocol. It would have killed three of the five real findings.A self-audit, not a study. I graded the verification gate I had built against ten cases whose outcomes I already knew: 40% recall, 50% precision, and two of the three false negatives were my own published CVEs. The design flaws in that number stated up front, the two specific failure modes (refutation-by-retry against a probabilistic effect, and mechanism mistaken for accepted consequence), the re-adjudication that reopened three of eight kills, and the part I did not want to find: a send-gate failure that my own review had predicted in writing before I clicked. read 2026 · 07 A compliance tool that has to be wrong out loud: freezing the test cases before the rules, and auditing my own claimsA free EU AI Act self-check for SMEs, built where being confidently wrong has legal consequences. Fourteen legal scenarios hash-frozen four hours before the first rule existed; a “your answers never leave the device” promise enforced by a CI test that asserts zero non-self requests; three-valued verdicts that refuse to guess (25,515 evaluations found no “compliant” resting on missing data). Plus the record of what adversarial passes killed in my own public claims, including a false statement in my own README, and the portability bug the gate caught that I could not. read 2026 · 07 Population-scale content scanning, measured: base-rate collapse and a fair evasion test on a deployed hashA reproducible CSAM-scanning case study. Modelled: even a good detector floods the innocent at scale (~99 in 100 flags innocent in the believed FPR regime), and I measured that regime’s false-match rate to lower-bound it. Measured on a deployed hash (Meta’s PDQ) plus open ones: evasion is hash-dependent and, under a query-budget-matched baseline and Holm-corrected multi-seed stats, mostly a measurement artifact for DCT hashes. Plus the record of the errors four adversarial red-team passes caught in my own numbers before publishing. Dated note on the EU “chat control” vote. read 2026 · 06 Incomplete-fix siblings on the AI and agent surface: a class-agnostic sibling-diff method and a public instance indexNot new bug classes, already-named ones (CWE-918 SSRF, OWASP API1/API5, CWE-284/285/862/863/639, CWE-79, the confused deputy, ATLAS AML.T0053). A reproducible sibling-diff and incomplete-fix method, a runtime oracle, a measured loss, and a public index of the live-published instances across SSRF, authorization, auth-bypass, and XSS. Flagship: open-webui CVE-2026-54008. read 2026 · 06 The token-exchange grant that skipped dex's connector allow-listGHSA-7qjx (CWE-285): dex enforced a client's connector allow-list on its other OAuth2 entry points but not on the token-exchange grant. A sibling-diff method writeup, and where the measurement honestly fits. read 2026 · 06 A confused deputy in GitHub's own MCP serverCVE-2026-48529: in lockdown mode, github-mcp-server bound every user's repo-access checks to the first user's token. A real instance of the class I work on, and an honest account of what a single disclosure is and is not worth. read 2026 · 06 Measuring whether my method beats a naive frontier-model callI built a benchmark to check it. On crypto a method won; on authz a static proxy of it didn't, and the runtime test recovered the case it missed. Telling those apart is the point. read

Also building · a broader AI portfolio

A BSc-AI student (University of Pavia) putting the most serious work into AI-security now, while building broadly across AI. A few of the more-developed threads:

ml research

Representation & continual learning

A continual-learning study on replay dynamics and phase transitions in fine-tuning, BinaryLLM (1-bit embeddings), and a neuro-symbolic Z3 prototype written up as an honest negative result.

high-performance systems

Vector search & LLM caches

edgevec, a Rust vector-search engine for browser and edge. Plus a 256-bit binary semantic cache for LLMs (Rust core, about 10 ms index load at 1M entries).

embodied AI

Open-source robotics

Open Duck Mini, an experimental open-source 12-DOF quadruped with IMU and servo firmware, plus a 3D-printed SO-ARM manipulator.

Production work: I build and maintain atala.it and whistlebikes.com for Atala, a historic Italian bicycle manufacturer.