blog.moksha.dk

Personal blog by Jakob Wolffhechel

I'm kind of a ghost 👻, so I got that going for me, which is great

Published 2026-05-25


How this started

I run ZFS, I run XAPI. I wanted to write a proper SMAPIv3 v5 storage driver for XCP-ng - using ZFS the way ZFS was designed to be used (raw zvols, native snapshots, native compression, zfs send/recv for migration), instead of qcow2-on-dataset wrappers pretending to be ZFS. Reading the XAPI codebase to figure out how to build that driver is what produced the XSA-489 disclosure. The XSA-489 outcome is what produced this audit.

The question

I knew mine were ghosts. But how many others were there?

Of all the CVEs referenced in Xen Security Advisories (XSAs), how many have a corresponding record in any of the 30+ vulnerability databases CIRCL's vulnerability-lookup indexes (NVD, cvelistv5, CSAF feeds, OSV, KEV, others)?

A CVE is a ghost if the advisory exists and is PGP-signed but the CVE record exists nowhere in those databases.

Method

Script + raw JSONL: audit-xsa.py, audit-results.jsonl.

Counts

580 CVEs total. 568 published. 12 ghosts.

Per year. Ghost % is the ghost rate within that year (ghosts / CVEs that year), not a share of the 12 ghosts overall. The trend is the story - 0% for 11 years, then 1.5% → 15.4% → 41.2%.

Year | CVEs | Published | Ghost | Ghost %
2011 |    6 |       6   |   0   |    0
2012 |   34 |      34   |   0   |    0
2013 |   49 |      49   |   0   |    0
2014 |   42 |      42   |   0   |    0
2015 |   52 |      52   |   0   |    0
2016 |   43 |      43   |   0   |    0
2017 |   45 |      45   |   0   |    0
2018 |   33 |      33   |   0   |    0
2019 |   33 |      33   |   0   |    0
2020 |   54 |      54   |   0   |    0
2021 |   45 |      45   |   0   |    0
2022 |   66 |      65   |   1   |  1.5
2023 |   27 |      27   |   0   |    0
2024 |    8 |       8   |   0   |    0
2025 |   26 |      22   |   4   | 15.4
2026 |   17 |      10   |   7   | 41.2

2026 is partial - 5 months of data through 2026-05-25; year ends Dec 31. 17 CVEs and 7 ghosts so far.

11 consecutive years (2011-2021) at 100% publication: 436 CVEs, 0 ghosts.

First ghost appears 2022. Volume rises in 2025-2026.

The 12 ghosts

YearXSACVEComponentReporterReporter affiliation
2022XSA-396CVE-2022-23041Linux PV netfrontDemi Marie Obenour, Simon Gaiserindependent
2025XSA-468CVE-2025-27462WinPVDrivers (XenCons)Tu DinhVates
2025XSA-468CVE-2025-27463WinPVDrivers (XenIface)Tu DinhVates
2025XSA-468CVE-2025-27464WinPVDrivers (XenBus)Tu DinhVates
2025XSA-474CVE-2025-58146XAPI (UTF-8)Edwin TorokXenServer
2026XSA-478CVE-2025-58151varstored (UEFI)Teddy AstieVates
2026XSA-483CVE-2026-23556oxenstoredAndrii SultanovVates
2026XSA-489CVE-2026-23559XAPI RBAC??
2026XSA-489CVE-2026-23560XAPI RBAC??
2026XSA-489CVE-2026-23561XAPI RBAC??
2026XSA-489CVE-2026-23562XAPI RBAC??
2026XSA-489CVE-2026-42486XAPI RBAC??

By reporter affiliation: 6 Vates, 1 XenServer, 1 independent, 5 from XSA-489.

XSA-396: Obenour + Gaiser reported 7 CVEs in one advisory. 6 published, 1 ghost. Same advisory, same authors, same reporting.

XSA-483: Sultanov reported 2 CVEs the same day. One published (XSA-484, hypervisor), one ghost (XSA-483, oxenstored).

Pattern: component layer

Splitting the 580 CVEs by component layer:

LayerCVEsGhostsGhost %
Hypervisor (Xen core, x86, EPT, IBPB)42500%
Linux kernel (PV frontends, privcmd)7011.4%
Management / toolstack (XAPI, xenstored, oxenstored, varstored, qemu, libxl, WinPVDrivers)851112.9%

11 of 12 ghosts (92%) are in the management/toolstack layer. The remaining ghost is in a Linux PV frontend (XSA-396 netfront). The hypervisor layer has never produced a ghost in 580 CVEs over 15 years.

The management/toolstack layer is where Citrix, XenServer/CSG, and Vates have diverged from upstream Xen and where their commercial products compete. The hypervisor layer is shared open-source code.

Pattern: editorial register

The 12 ghosts fall into four shapes:

  1. Named-but-record-withheld (most of the list). Reporter is named in the advisory text. CVE number is assigned and printed on xenbits. The CVE record never appears in NVD or anywhere else CIRCL indexes. 7 of the 12 fit this shape.
  2. Downplayed. Reporter named. Severity language soft. CVSS lower than reporter's assessment. XSA-396 partially fits.
  3. Silently fixed. Advisory acknowledges a class of bugs without breaking them out as individual CVEs. Hard to count by definition.
  4. Refused-to-credit + disparaged + record-withheld. XSA-489, only. Advisory text: "explicitly not credited" and "AI hallucinations." 5 CVEs - 42% of all ghost CVEs in 15 years come from this one advisory. This shape has no precedent in the 15-year XSA history. 💪😎👍

Consequence

CVE records are what vulnerability scanners (Nessus, Qualys, Rapid7, OpenVAS, etc.) consume. No record in the databases means no scanner rule. Organizations running XCP-ng or XenServer with these patched vulnerabilities cannot use automated tooling to verify exposure or patch state. Manual cross-reference against xenbits.xen.org is the only option.

Method, data, contact

Jakob Wolffhechel · Moksha · Copenhagen · jakob@wolffhechel.dk · +45 3170 7337 · Advisories