Skip to content

Tool: lookup_vulns

Read the full advisory for a vulnerability id: the complete description body, the affected version ranges, the CWE, and the machine-readable statement of which configurations are vulnerable. Served from k9's curated corpus of VulnCheck NVD++ and OSV.dev data.

Ask your agent:

Read the full advisory for CVE-2024-21501 and tell me whether that condition exists in our code.

A scanner alert carries an advisory summary, and summaries routinely omit the fact that decides reachability: the configuration option that enables the flaw, or the precondition an attacker needs. CVE-2024-21501 in sanitize-html is a fair example. Its summary says "Information Exposure vulnerability". Its body says the package is vulnerable "when used on the backend and with the style attribute allowed", which is a condition you can go and check in your own configuration. An agent working from the summary alone has nothing to check for, and grounded reachability analysis stalls at undetermined.

Call this tool before settling for undetermined. The rubric's basis-selection procedure points here for exactly that case: read the body, find the precondition, then check your code for it.

Prefer it over fetching advisory pages from the internet. This tool serves a corpus k9 manages, and it works in egress-restricted environments where a call to a public advisory site is blocked, which is the normal situation for a coding agent running under a security policy.

Request

lookup_vulns(vuln_ids)
  • vuln_ids: a list of vulnerability ids, max 10 per call. Case- and whitespace-insensitive.

Any id resolve_vuln_ids knows works here. Send a GHSA and you get its advisory whether k9 files the record under that GHSA or under its CVE, because aliases resolve to the same record.

lookup_vulns limits input to 10 vulnerability ids because advisory bodies are served whole and some run to several KB of markdown. Truncating them would defeat the point of the tool, since the sentence you need is as likely to be at the end as the beginning.

Duplicates collapse before the limit is counted. Two spellings of one id count as two, though, because the response is keyed as you sent it.

{
  "vuln_ids": [
    "CVE-2024-21501",
    "GHSA-537c-gmf6-5ccf"
  ]
}

Response

A dictionary keyed by your input id, echoed exactly as you sent it. Every id you send comes back. Absent fields are omitted rather than returned as null, so test for absence.

Field Type Description
vuln_id string The id, as you sent it.
in_catalog bool Whether k9's catalog knows this id.
cve string The advisory's canonical CVE. Absent when the advisory genuinely has none.
osv_id string The OSV advisory id, in its published casing. Absent when no OSV advisory covers the id.
aliases list of strings Other known ids for the same vulnerability, in the catalog's upper-case form. The id you asked about and its cve are excluded.
summary string One-line description. The OSV summary when there is one, otherwise the NVD description.
details string The full advisory body, markdown, served whole. OSV-sourced, so absent on records only NVD covers.
affected list OSV's affected packages, version ranges, and events, verbatim.
cwe list of strings The weakness classes, often more than one, e.g. ["CWE-200", "CWE-538"]. NVD-sourced.
configurations list NVD's applicability statement, verbatim: which products, versions, and configuration combinations are vulnerable.
references list of strings Deduplicated URLs from both sources, OSV's first.
published string When the advisory was published.
modified string When it was last changed.
data_age_seconds int Seconds since the catalog was last loaded. The corpus refreshes daily, so under 86400 is fresh.

A real response from these two ids, trimmed. The details bodies are shown whole; the long affected, configurations, and references lists are cut at the ellipses, and a real response carries them in full.

{
  "CVE-2024-21501": {
    "vuln_id": "CVE-2024-21501",
    "in_catalog": true,
    "cve": "CVE-2024-21501",
    "osv_id": "GHSA-rm97-x556-q36h",
    "aliases": ["GHSA-RM97-X556-Q36H"],
    "summary": "sanitize-html Information Exposure vulnerability",
    "details": "Versions of the package sanitize-html before 2.12.1 are vulnerable to Information Exposure when used on the backend and with the style attribute allowed, allowing enumeration of files in the system (including project dependencies). An attacker could exploit this vulnerability to gather details about the file system structure and dependencies of the targeted server.",
    "affected": [
      {
        "package": {
          "name": "sanitize-html",
          "ecosystem": "npm",
          "purl": "pkg:npm/sanitize-html"
        },
        "ranges": [
          {
            "type": "SEMVER",
            "events": [{ "introduced": "0" }, { "fixed": "2.12.1" }]
          }
        ]
      }
    ],
    "cwe": ["CWE-200", "CWE-538"],
    "configurations": [
      {
        "nodes": [
          {
            "operator": "OR",
            "cpeMatch": [
              {
                "vulnerable": true,
                "criteria": "cpe:2.3:a:apostrophecms:sanitize-html:*:*:*:*:*:node.js:*:*",
                "versionEndExcluding": "2.12.1"
              }
            ]
          }
        ]
      }
    ],
    "references": [
      "https://nvd.nist.gov/vuln/detail/CVE-2024-21501",
      "https://github.com/apostrophecms/sanitize-html/pull/650",
      "..."
    ],
    "published": "2024-02-24T06:30:17Z",
    "modified": "2026-07-02T17:59:21.175724605Z",
    "data_age_seconds": 52
  },
  "GHSA-537c-gmf6-5ccf": {
    "vuln_id": "GHSA-537c-gmf6-5ccf",
    "in_catalog": true,
    "osv_id": "GHSA-537c-gmf6-5ccf",
    "summary": "Vulnerable OpenSSL included in cryptography wheels",
    "details": "pyca/cryptography's wheels include a statically linked copy of OpenSSL. The versions of OpenSSL included in wheels prior to cryptograph 48.01 are vulnerable to a security issue. More details about the vulnerability itself can be found in https://openssl-library.org/news/secadv/20260609.txt.\n\nIf you are building cryptography source (\"sdist\") then you are responsible for upgrading your copy of OpenSSL. Only users installing from wheels built by the cryptography project (i.e., those distributed on PyPI) need to update their cryptography versions.",
    "affected": ["..."],
    "references": [
      "https://github.com/pyca/cryptography/security/advisories/GHSA-537c-gmf6-5ccf",
      "..."
    ],
    "published": "2026-06-15T20:12:27Z",
    "modified": "2026-06-16T19:59:26.897634900Z",
    "data_age_seconds": 30
  }
}

The two entries come from different sources. The first is covered by both OSV and NVD, so it carries a body alongside NVD's cwe and configurations. The second has no CVE, because the flaw is in an OpenSSL copy statically linked into the cryptography wheels, so there is no NVD record and no cwe or configurations with it. It is served under its own id, the same convention resolve_vuln_ids follows.

The second body also draws a line the summary does not: users who install the project's PyPI wheels are affected, users who build from source are not. That decides whether the alert applies to you at all.

Three response shapes

An entry comes back in one of three shapes.

  • in_catalog: false. k9's catalog does not know the id. You get vuln_id, in_catalog, and data_age_seconds, nothing more.
  • in_catalog: true with body fields. The normal case.
  • in_catalog: true with no body fields. k9 has no verified detail for this id. Malicious-package advisories are the common case, since they are deliberately kept out of the detail corpus. Read this as "no detail available," never as evidence that the vulnerability is safe or unexploitable. The absence describes k9's corpus, not the vulnerability.

Which fields come from where

details and affected come from OSV, which covers reviewed advisories across the major package ecosystems. cwe and configurations come from NVD, which covers CVEs regardless of ecosystem. So a CVE with no OSV advisory, common for operating-system packages and firmware, returns summary, cwe, configurations, and references with no details body.

When both sources describe the same vulnerability, OSV wins for summary, published, and modified, and references merges both.

Errors

Sending more than 10 ids raises an error naming the count. Split the batch and call again.

If the server has just started, the call may ask you to retry shortly while the catalog loads.


Last update: August 5, 2026