A CVE identifier is a name for one vulnerability in one product, assigned by an organisation authorised to assign it, and published as a record that other tools can match against software they find. That narrow definition is the reason CVE works: scanners can say package X at version Y is affected, and a patch can say it is not. AI systems strain the definition. Some of their flaws are ordinary bugs in ordinary code and fit perfectly. Others live in model behaviour, have no version to bump and no package to match, and fit badly or not at all.
This article treats CVE as an operating process for teams that build or run AI systems. It covers what gets a CVE and what does not, what real AI CVEs look like, how to triage incoming CVEs against an AI stack using reachability and VEX, how to score them when the attacker reaches you through a model, and how to issue a record for your own product. The landscape of databases and classification schemes is covered in AI vulnerability databases, and the human side of reporting in responsible disclosure for LLM vulnerabilities; here the focus is the record itself and the work around it.
How the CVE system works
Four roles matter. The CVE Program, run by MITRE under US government sponsorship, maintains the list and the rules. CVE Numbering Authorities (CNAs) assign identifiers within a published scope: many large vendors and open-source foundations are CNAs for their own products, and some security firms and bug-bounty platforms are CNAs for products they research. A root or a CNA of last resort covers products with no CNA of their own. Downstream, enrichment services such as the NVD add CVSS scores, CWE classes and CPE product names, while GitHub Security Advisories and OSV map CVEs to package ecosystems and version ranges that dependency scanners can use.
The record is the CNA's product. It names the affected product and version ranges, describes the flaw, lists references, and since the CNA Rules 4.0 (2024) can carry CVSS, CWE and CPE data supplied by the CNA itself. Those rules also state that assignment is technology neutral, naming cloud and artificial intelligence explicitly. That settles the question of whether AI products can get CVEs. It does not settle which AI flaws qualify, because each CNA decides that within its own scope definition.
Two operational facts shape how you consume CVEs. In 2024 the NVD fell far behind on enrichment, leaving many new CVEs without NVD scores or product mappings for months. In April 2025 the MITRE contract that funds the program came close to lapsing before CISA extended it. Neither event stopped CVE IDs being assigned, but both argue against building triage on a single feed. Pull from the CVE record, GHSA and OSV, and treat NVD enrichment as one input.
What in an AI system gets a CVE
The useful test is whether there is a vendor, a product, an affected version range and a fix that changes the version. Walk an AI system layer by layer and the answer varies.
| Layer | Example flaw | CVE fit |
|---|---|---|
| Serving and tooling code | Path traversal in a model server API | Good: versioned code, clear fix |
| Loaders and formats | Code execution while deserialising weights | Good: library version fixes it |
| Agent and chain glue | Model output passed to exec or a shell | Good: the bug is in the glue code |
| Hosted model behaviour | A jailbreak against an API model | Poor: no customer-side version; often out of CNA scope |
| A specific weights file | Backdoored or malicious model on a hub | Poor: usually a malware or takedown report |
| Prompt injection by design | Assistant follows instructions in a document | Mixed: CVE when a product lacks a control it claims |
Some CNA scope definitions explicitly exclude model behaviour issues such as jailbreaks, hallucinations and policy bypasses, routing them to safety reporting instead. The pattern that does get CVEs is a model-mediated flaw in code: a framework turns model output into an action without the control the product promised. The model is the delivery mechanism; the vulnerability is in the code that trusted it. CWE now has a class for the input side of this, CWE-1427, Improper Neutralization of Input Used for LLM Prompting, alongside long-standing classes like CWE-94 code injection, CWE-22 path traversal and CWE-502 deserialisation of untrusted data.
Three real AI CVEs
Three published CVEs show the shapes worth recognising.
- CVE-2023-29374, LangChain. LLMMathChain asked a model to write Python for a maths question and ran it with exec. A prompt that persuaded the model to emit arbitrary code got arbitrary code execution; versions through 0.0.131 were affected and it was scored 9.8 under CVSS 3.1. This is the model-mediated pattern in its plainest form.
- CVE-2024-37032, Ollama, nicknamed Probllama. Before 0.1.34 the server did not validate the digest field of a model manifest, so pulling a model from a malicious registry could write files outside the model directory. Wiz showed this leading to remote code execution. No model is involved in the flaw; it is a classic path traversal in AI infrastructure, which is the commonest kind of AI CVE.
- CVE-2025-32434, PyTorch.
torch.load(..., weights_only=True)was widely recommended as the safe way to load untrusted checkpoints, yet versions up to 2.5.1 could still be driven to code execution by a crafted file. Fixed in 2.6.0, scored 9.3 under CVSS 4. The lesson is that a mitigation is also code with versions, and the CVE is how you learn it failed.
Each of these has what a scanner needs: a package name, an ecosystem and a version boundary. That is why they flow through dependency tooling and why behaviour flaws, which lack all three, do not. The loader risks behind the third example are covered in supply chain attacks on ML.
The lifecycle in both directions
The lifecycle has a producing half and a consuming half. A finding reaches a CNA whose scope covers the product; the CNA reserves an ID, the vendor fixes under embargo, and the CNA publishes a record in CVE JSON 5 format. Feeds pick it up within hours. On the consuming side, scanners match it against what you run, someone decides whether it matters, and you either patch or record why you are not affected.
For AI teams the consuming half is larger: Python packages, CUDA libraries, base images, an inference server, an agent framework and unpinned notebooks each bring their own stream of CVEs.
Triage: matching, reachability and VEX
Start from an inventory, because a CVE you cannot match is a CVE you cannot triage. Generate it from lockfiles and images rather than from memory, and include the inference server and model loaders, not only application packages. Then query a feed. The OSV API accepts a package, ecosystem and version and returns matching advisories with their CVE aliases; the sketch below batches that check across a lockfile.
import json, urllib.request
OSV = "https://api.osv.dev/v1/query"
def advisories(name, version, ecosystem="PyPI"):
body = json.dumps({"package": {"name": name, "ecosystem": ecosystem},
"version": version}).encode()
req = urllib.request.Request(OSV, body, {"Content-Type": "application/json"})
with urllib.request.urlopen(req, timeout=20) as r:
return json.load(r).get("vulns", [])
def triage(lock): # lock: {"torch": "2.5.1", "langchain": "0.0.120"}
rows = []
for name, ver in sorted(lock.items()):
for v in advisories(name, ver):
cves = [i for i in [v["id"], *v.get("aliases", [])] if i.startswith("CVE-")]
rows.append({"package": name, "version": ver, "id": v["id"],
"cves": cves, "summary": v.get("summary", "")[:90]})
return rows
for row in triage({"torch": "2.5.1", "langchain": "0.0.120"}):
print(row)A match is the start of triage, not the end. For each one, answer four questions in order: is the vulnerable function reachable from how we use the package; is the input that triggers it attacker-influenced, remembering that in an AI system that includes anything the model reads; what does exploitation give the attacker in our deployment; and is a fixed version compatible with our pinned CUDA and model stack. The last question is where AI teams lose weeks: the fix for a loader CVE may need a framework upgrade that changes numerics or breaks a custom kernel.
Record the outcome in VEX, a machine-readable statement attached to your product. OpenVEX uses four statuses, not_affected, affected, fixed and under_investigation, and a not_affected statement carries a justification such as vulnerable_code_not_in_execute_path. VEX turns a one-off judgement into something your customers' scanners can consume, and stops the same false positive being re-triaged every week.
Scoring when the attacker reaches you through a model
CVSS scores the flaw in the abstract; your risk depends on deployment. AI systems shift two inputs in particular. First, attack vector and privileges: when model output reaches a vulnerable sink, the attacker is anyone who can put text in front of the model, including authors of web pages, emails, tickets and retrieved documents. A bug that looks local or authenticated in the base score can be network-reachable and unauthenticated in a retrieval-augmented agent. Second, impact: inference servers often hold model weights, API keys for tools and GPU nodes with broad network access, so code execution there is worth more than on a typical web worker.
Use the base score to sort, then adjust with environmental metrics or your own severity rubric, and add exploitation signals: EPSS probability and presence in CISA's Known Exploited Vulnerabilities catalogue. Self-hosted model servers exposed to the internet without authentication are routinely found by scanning, so treat their CVEs as internet-facing by default.
Issuing a CVE for your own AI product
If you ship AI software others run, a library, a server, an agent framework or an on-premises product, you will need to issue CVEs. Decide first who your CNA is. Large vendors and foundations become CNAs; smaller projects use GitHub's CNA through a repository security advisory, or the CNA of their hosting foundation. Publish a scope statement that says plainly which classes you assign for, including whether model-mediated flaws in your code qualify and whether behaviour of hosted models does.
A good record names the product exactly as package managers do, gives precise version ranges, says what an attacker needs and gets, and picks the most specific CWE. An abridged CNA container for a model-mediated flaw looks like this:
{
"affected": [{"vendor": "example", "product": "agentkit",
"versions": [{"version": "1.4.0", "lessThan": "1.7.2",
"status": "affected", "versionType": "semver"}]}],
"descriptions": [{"lang": "en", "value": "The shell tool in agentkit 1.4.0 before 1.7.2 runs commands proposed by the model without the documented allowlist check when tool_mode is auto. Content the model reads, such as a retrieved document, can cause arbitrary command execution as the agent user."}],
"problemTypes": [{"descriptions": [{"lang": "en", "type": "CWE", "cweId": "CWE-78",
"description": "CWE-78 OS Command Injection"}]}],
"references": [{"url": "https://github.com/example/agentkit/security/advisories/GHSA-xxxx"}]
}The description does not blame the model or promise prompt-level fixes: the fix is the allowlist check, and a scanner can act on the version boundary. Coordinate timing through your disclosure policy; the planning questions are covered in AI vulnerability disclosure norms.
Worked example: one week, two CVE decisions
A team runs a retrieval-augmented support agent: a Python service using an agent framework, PyTorch for a local reranker, and a self-hosted inference server. In one week two things happen.
Incoming. The scanner flags CVE-2025-32434 against torch 2.5.1. Triage: the reranker loads one checkpoint, built in-house, with weights_only=True. The trigger needs an attacker-supplied checkpoint, and none is loaded from outside. Status not_affected, justification vulnerable_code_not_in_execute_path, plus a ticket to upgrade at the next CUDA bump, because the reasoning depends on a process that could change. The VEX statement records that dependency so a future reviewer can re-check it.
Outgoing. A red-team exercise shows that a document in the knowledge base can make the agent call an internal HTTP tool with arbitrary URLs, reaching metadata endpoints. The team ships the agent framework as an open-source package too. The flaw is a missing URL allowlist in their tool wrapper, versioned code with a clean fix, so it qualifies. They file a repository advisory, request a CVE through it, choose CWE-918 server-side request forgery with CWE-1427 noted in the description, publish with the fixed version, and add a regression test that replays the injected document. The jailbreak variants found in the same exercise go to the model provider's safety channel instead, with no CVE.
Failure modes
- Single-feed triage. Relying on NVD alone during its enrichment backlog left new CVEs unscored and unmatched. Use several feeds.
- Blind spots in inventory. Notebooks, training images and model servers deployed by hand are where unscanned CVEs live.
- Base-score complacency. A medium score on a sink reachable by model output is often critical in an agent.
- CVE requests for behaviour. Filing jailbreaks as CVEs wastes CNA time and is usually rejected; route them to safety reporting.
- Vague records. Missing version ranges or a product name that does not match the package make your CVE invisible to scanners.
- Stale VEX. A not_affected judgement that depended on usage becomes false when usage changes. Review VEX when code paths change.
Trade-offs
Becoming a CNA gives control over timing and wording but costs process and staffing; using a platform CNA is cheaper but slower. Publishing VEX reduces customer noise but makes you accountable for each judgement. Upgrading fast closes exposure but risks numerical regressions in model stacks; pinning keeps reproducibility but accumulates CVEs. Most teams should patch internet-facing serving components quickly and batch training-stack upgrades with a regression run.
What to do next
- Generate an inventory from lockfiles and images, including inference servers, model loaders and notebooks.
- Run the OSV check above, or osv-scanner or pip-audit, on every build and on a daily schedule against deployed images.
- For each match, answer the four triage questions and record the result as a VEX statement with a justification.
- Mark every component where model output reaches code execution, file paths, URLs or shell, and treat CVEs there as network-reachable.
- If you ship AI software, choose your CNA route and publish a scope statement covering model-mediated flaws.
- Add a regression test for every CVE you fix, replaying the triggering input, including injected documents.