KEV (Known Exploited Vulnerabilities) - Potential Format (BCP-07)

KEV Assertion Format – Draft Specification (potential BCP-07)

This format describes a generic KEV (Known Exploited Vulnerability) assertion format.
The goal is to express who claims exploitation, when, based on what, where it was observed, and with which level of confidence, without turning KEV into full threat intelligence. A KEV assertion is usually very binary and lacking some meta-information. The format adds some information which could better capture details about the exploitation. A majority of the fields are optional except vulnerability, status and evidence.[].source which are recommended.

Format

It’s a single JSON object (ECMA 404) per KEV entry. The KEV entry is associated to a vulnerability ID in GCVE ID.

Sample

{
"vulnerability": {
    "vulnId": "GCVE-0-2025-55182"
  },
 "status": {
    "exploited": true,
    "status_reason": "confirmed",
    "status_updated_at": "2025-12-24T10:15:00Z"
  },
 "characteristics": {
    "remote_code_execution": true,
    "authentication_required": false,
    "local_access_required": false
  },
 "timestamps": {
    "first_seen_at": "2025-12-03T10:15:00Z",
    "asserted_at": "2025-12-05T12:10:11Z",
    "recorded_at": "2025-12-05T13:15:00Z",
    "last_seen_at": "2025-12-24T09:42:21Z"
  },
 "scope": {
    "observation_regions": ["Europe", "North America"],
    "victim_countries": ["LU","BE", "US", "CA"],
    "sector": ["Telecoms", "Aerospace"],
    "asset_exposure": ["internet-facing"],
    "notes": "Regions reflect observed evidence, not global exclusivity."
  },
"evidence": [
    {
      "type": "incident_response",
      "signal": "confirmed_compromise",
      "confidence": 0.9,
      "source": "national-csirt",
      "details": {
        "observed_outcome": ["initial-access", "rce"],
        "detection_basis": ["forensics", "log-analysis"]
      }
    },
    {
      "type": "honeypot",
      "signal": "in_the_wild_attempts",
      "confidence": 0.6,
      "source": "research-honeynet",
      "details": {
        "attempt_volume": "high",
        "successful_exploitation": false
      }
    }
  ],
  "references": [
    {
      "id": "GCVE-0-2025-55182",
      "url": "https://vulnerability.circl.lu/vuln/CVE-2025-55182#sightings"
    }
  ],
}

Field Description

vulnerability Object

Describes the vulnerability being asserted as exploited.

vulnerability.vulnId
  • Type: string
  • Required: yes
  • Description: GCVE, CVE identifier, GHSA or any identifier of the vulnerability.
  • Example: "GCVE-0-2025-55182"

status Object

Represents the current exploitation status.

status.exploited
  • Type: boolean
  • Description: Indicates whether exploitation has been observed or asserted.
  • Semantics: Does not imply global prevalence or universal exploitability.
status.status_reason
  • Type: string (enum)
  • Allowed values: confirmed, suspected, disputed, historical, unknown
  • Description: Rationale behind the exploitation status.
status.status_updated_at
  • Type: string (RFC3339 datetime)
  • Description: Timestamp of the last change to the exploitation status in the KEV assertion.

characteristics Object

Describes high-level technical characteristics of the vulnerability that are relevant to exploitation assessment, without providing exploit details or turning the KEV assertion into full threat intelligence.

These fields describe properties of the vulnerability itself, not necessarily every observed exploitation instance.

characteristics.remote_code_execution
  • Type: boolean
  • Description: Indicates whether successful exploitation can result in remote code execution.
  • Notes: Does not imply exploit reliability or ease of weaponization.
characteristics.authentication_required
  • Type: boolean
  • Description: Indicates whether authentication is required to exploit the vulnerability.
  • Notes: Reflects the weakest known exploitation path.
characteristics.local_access_required
  • Type: boolean
  • Description: Indicates whether local system access is required prior to exploitation.
  • Notes: Useful to distinguish remote exploitation from post-compromise privilege escalation.

timestamps Object

Separates different notions of time to avoid ambiguity.

timestamps.first_seen_at
  • Type: string (ISO-8601 datetime)
  • Description: Earliest known exploitation activity based on technical observation.
  • Notes: May be estimated and updated retroactively.
timestamps.asserted_at
  • Type: string (RFC3339 datetime)
  • Description: Date when an authority or source officially declared exploitation.
  • Notes: Mirrors fields such as “date added” in KEV lists.
timestamps.recorded_at
  • Type: string (RFC3339 datetime)
  • Description: Timestamp when this assertion was ingested or recorded by the collector.
  • Notes: System-specific and independent of the source.
timestamps.last_seen_at
  • Type: string (RFC3339 datetime)
  • Description: Most recent confirmed observation of exploitation activity.
  • Notes: Optional and often unavailable.

scope Object

Defines the observed context of exploitation.

scope.observation_regions
  • Type: array of strings
  • Description: Geographic regions where exploitation evidence was observed. The region can be described in UN M49 format to facilitate automation.
  • Notes: Reflects sensor or reporting coverage, not global limits.
scope.victim_countries
  • Type: array of strings
  • Description: Countries in ISO 3166 where confirmed victims were identified.
  • Notes: Often incomplete or unavailable.
scope.sector
  • Type: array of strings
  • Description: Sectors targeted or affected by exploitation. The sector SHALL come from the MISP galaxy sector.
  • Example: "Telecoms", "Aerospace"
scope.asset_exposure
  • Type: array of strings
  • Allowed values: internet-facing, internal, vpn-accessible, unknown
  • Description: Exposure context of affected assets.
scope.notes
  • Type: string
  • Description: Human-readable clarifications to prevent misinterpretation.

evidence Array

Collection of independent signals supporting the exploitation claim.

evidence[].type
  • Type: string (enum)
  • Allowed values: incident_response, telemetry, honeypot, sinkhole, vendor_report, research_report, unknown
  • Description: Origin of the exploitation evidence.
evidence[].signal
  • Type: string (enum)
  • Allowed values: (can be multiple) in_the_wild_attempts, successful_exploitation, confirmed_compromise, mass_scanning, weaponized_exploit_available
  • Description: Nature of the observed exploitation signal.
evidence[].confidence
  • Type: number (0.0–1.0) or enum
  • Description: Confidence level associated with this evidence.
evidence[].source
  • Type: string
  • Description: Logical identifier of the reporting entity or data source. MISP org UUID? What about existing KEV source like CISA, ENISA or alike. Should we have an enum with existing ones? The source would be the only required fields has many KEV like the type of signal.
evidence[].details
  • Type: object
  • Description: Structured, free-form metadata describing how the signal was derived.
  • Notes: Content is implementation-specific.
1 Like

Open Questions

  • Where is the dueDate field?
    This field exists in the CISA KEV, but its actual purpose is unclear.
    Is it actively used in practice?
    Is the due date tied to the availability of a fix or remediation, or is it purely a policy-driven deadline?

  • Why are CWEs not included?
    Should CWEs be referenced at all, or would that simply duplicate information already implied by the vulnId (CVE)?
    If included, what additional value would CWEs provide in a KEV context?

  • Should CPEs or affected versions be included?
    Including CPEs or version information could make sense, especially for telemetry and detection use cases, where knowing the exact exploited versions matters more than the abstract vulnerability identifier.

Does it make sense to have status.exploited: false ? If so, what are the field that shoud (not) be allowed ?

Can the date be in RFC3339 datetime format instead of ISO-8601 format to have a publicly accessible and redistribuable specification ?

Very good point. It’s fixed.

the false should mean a failure of exploitation? like a TA tries the exploitation unsuccessfully ? or it means we haven’t seen anything exploited. I see the use-case of the vendor, always claiming it’s not exploited and other showing the opposite. The format allows to have two different sources claiming the opposite. In all the cases, a source might be required too and the vulnId too.

The failure of exploitation should be defined with evidence[].signal: in_the_wild_attempsif I understand correctly. In fact, I’m not sure this should be allowed since we are talking about Know exploited vulnerabilities. Or maybe for a honeypot to publish it has not seen it, but the field should maybe be renamed seen

1 Like

Also, the JSON format should be specified to avoid some compatibility issues later. Either use the ECMA 404 definition or the JSON5 one. I think the ECMA definition is sufficient since we don’t need NaN and the compatibility is greater.

I’d like to weigh in on a few of the open questions here.

On Granularity (CPEs/Versions):
I believe a software identifier of some type should be mandatory. While the vulnId (CVE/GCVE) is the anchor, practical detection and remediation often require knowing the specific implementation context. Whether it is a CPE, PURL, or even a Git Hash, having that precise target is significantly “better than nothing” for defenders trying to prioritize.

On CWEs vs. Threat Characteristics:
I am usually the target audience for CWEs (data science/aggregation), but in the context of a KEV assertion, I don’t think adding them explicitly adds much differentiation.

However, instead of a CWE, I would strongly support a characteristics object containing high-signal flags. Knowing how it is exploited is more critical than the academic classification. For example:

"characteristics": {
  "remote_code_execution": true,
  "authentication_required": false,
  "local_access_required": false
}
  • remote_code_execution: Can this be executed without physical access?
  • authentication_required: Does the attacker need valid credentials?
  • local_access_required: Does this require an already compromised machine?

These flags provide immediate triage value that a generic CWE often obscures.

On “Disputed” Status & Trust:
This is arguably the hardest sticking point for any KEV format. If we don’t draw a hard line at “public exploit code available”, we inevitably end up needing a trust rating model. There is a massive difference between a KEV assertion coming from a major vendor/Project Zero and one coming from a random account on X. The evidence object might need a way to weigh the “reputation” of the source, or we accept that “disputed” will be a common state without a central authority.

On Due Dates & Timestamps:
I don’t see a need for a dueDate field—that feels like policy logic overlaying technical data. However, the timestamps object is critical. The current draft looks correct here: we absolutely need distinct fields for when the record was created (asserted_at) vs. when the exploitation was actually observed (first_seen_at).

On Evidence Sources:
To the point on evidence[].source—this needs to point to a verifiable, real-world source that a human analyst can check. It shouldn’t just be an abstract ID; it needs to lead to the proof.

1 Like

Based on the feedback from CERT-EU, I moved from industries to sector and the need to use the sector definition from MISP galaxy.

Thanks a lot for the very insightful details and feedback.

characteristics

The characteristics field is indeed a very good point. We have added it to the draft specification and currently consider this object to be optional.

"characteristics": {
  "remote_code_execution": true,
  "authentication_required": false,
  "local_access_required": false
}

source and evidence

Regarding evidence sources, this remains a challenging aspect. Even well-established sources such as CISA or other national or regional authorities are typically not very explicit in their KEV publications about the underlying evidence.

For example, it is often unclear whether an entry is based on:

  • a constituent report,
  • partial telemetry,
  • or confirmed digital forensic evidence.

One possible direction could be to normalize evidence sources or proof types via a defined vocabulary, effectively making the basis of the KEV assertion more explicit. However, this may go beyond what current KEV publishers are willing or able to disclose.

For the time being, it may be preferable to keep this discussion open and see whether organizations such as CISA or ENISA would be willing to provide feedback or guidance on this aspect.

Due dates and timestamps

I believe we generally agree on this point. Due dates were intentionally not included in the current specification. If stakeholders from the policy or regulatory domain strongly advocate for their inclusion, we could consider adding them as an optional field. I will add a note in the specification to reflect this possibility.

“Disputed” status and trust

This is arguably the most challenging topic. The current idea is that the status.exploited field would be set to false for organizations explicitly claiming that a vulnerability is not exploited, while the status_reason field can be used to indicate a disputed state.

I will add a clarification to the specification document to make this behavior explicit.

We will issue a first BCP-07 with this first draft and comments/updates are more than welcome.

First draft published at

Thanks a lot for all the contributions.

Typo fixed based on the following feedback

and concerning the practical information about the vulnerability management it should be outside the KEV format IMHO.

“Known Exploited Vulnerabilities“ or “Known Exploited Vulnerability“, but not “Known Exploited Vulnerabilitie“.

It appears as “Known Exploited Vulnerabilitie“ three times in title and section titles, and once as “Known Exploited Vulnerability“.

Thanks for the review. I fixed the typos.

1 Like

GCVE-0-2025-55182 : an example

btw why is “G” in front? What means?

They are only already known exploited vulnerabilities.

Currently I work only with CVE-XXX.. sth

G is related to geolocation or something else?

merci

It’s a GCVE id. The KEV format support all IDs including GHSA, CVE Program ID, CNVD or any id referring a security vulnerability advisory.

1 Like