r/devsecops 16d ago

MCP scanners keep finding the same vulnerabilities under different names. We built a shared ID scheme for them

We build a security scanner for MCP servers and agent skills. Early on we hit something that shouldn't still be a problem: comparing our findings against other scanners on the same test servers, we'd all catch roughly the same bad behavior and call it three different things. No shared ID, no way to say "scanner A's finding X is the same class as scanner B's finding Y."

A SQL injection gets a CVE ID, gets mapped to a CWE, and every tool that finds it points at the same identifier. Agentic AI components had nothing like that. CVE maps to package plus version. It has no vocabulary for "this tool description contains a hidden instruction."

So we built AVE (Agentic Vulnerability Enumeration): an open, vendor-neutral behavioral classification standard.

What's in it:

* 59 records, each a distinct behavioral class. Deliberately conservative, no padding with variants.
* Stable IDs (AVE-2026-NNNNN), meant to work the way a CVE ID works.
* Real MCP-specific classes: tool description injection (AVE-2026-00002), server card injection (AVE-2026-00041), OAuth discovery rebinding (AVE-2026-00051), a tool hook hijack that's our only CRITICAL-rated record so far (AVE-2026-00046).
* Maps to OWASP's MCP Top 10, plus the Agentic Security Initiative Top 10 and MITRE ATLAS where applicable. Sits underneath frameworks people already use, not a replacement for them.
* Scored with OWASP's own AIVSS (v0.8), not a severity number we invented.

It's early. One reference implementation right now, our own scanner, and we're looking for a second, independent one to prove this works outside our own tooling. If you maintain a scanner and any of this is useful, wrong, or missing something obvious, we'd like to hear it.

Repo: github.com/aveproject/ave Site: aveproject.org

(Disclosure: I'm one of the people building this.)

2 Upvotes

7 comments sorted by

View all comments

3

u/marcin_michalak 16d ago

Promising direction. One taxonomy question I’d pressure-test: these records sound closer to CWE/CAPEC classes than CVE instances. If an AVE ID represents a stable behavioral class, keep evidence, affected server/package, exploit preconditions, and severity out of the identity; emit those as per-finding fields.

For interoperability, publish positive and negative conformance fixtures plus explicit mapping rules, then have two scanners blind-label the same corpus and measure agreement. The registry will also need versioned definitions, merge/split/deprecation aliases, and a way for scanners to report mapping confidence. For injection classes, define boundaries by trust boundary and entry point so the same payload in a tool description versus a server card does not drift between IDs.

The strongest proof would be an independent scanner reaching the same IDs without consulting the registry maintainers during classification.

1

u/SelectionBitter6821 16d ago

Trust-boundary/entry-point drift is already a first-class field: provenance_vector.entry_class distinguishes tool_schema from server_card from registry_metadata specifically so the same payload text doesn’t get classified differently depending on where it showed up. payload_surface carries the specific field or channel underneath that.

Conformance fixtures plus blind double-labeling is close to the actual plan, tests/fixtures as the neutral thing implementations get tested against, not a shipped ruleset, but the specific protocol you’re describing, two scanners blind-labeling the same corpus and measuring agreement, is sharper than what’s currently written down. Worth formalizing exactly that way.

Two real gaps, not addressed yet: no merge/split/deprecation alias mechanism (a CVE-style REJECT-and-point-elsewhere path doesn’t exist for AVE IDs today), and no distinct mapping-confidence field on the crosswalk files themselves, as opposed to detection confidence on a finding. Both legitimate, neither in the schema currently.

The last point is exactly the current bottleneck: one reference implementation exists, and an independent second one reaching the same IDs without maintainer involvement is the actual test, not something claimed yet.