MOKSHA-2026-0064: Database Field Poisoning via VDI.xenstore_data Arbitrary Keys

Advisory IDMOKSHA-2026-0064
Semantic IDVXD-1
Published2026-04-24
CVSS 3.15.3 Medium
CVSS 3.1 VectorAV:N/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:N
CVSS 4.05.3 Medium
CVSS 4.0 VectorAV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
XAPI ObjectVDI
XAPI Fieldxenstore_data
Entry Rolevm-admin
ResearcherJakob Wolffhechel, Moksha

Affected Products

VendorProductVersions
Citrix / Cloud Software GroupXenServer / Citrix Hypervisorall versions (shared XAPI codebase)
VatesXCP-ng8.3.0

Summary

A vm-admin in XAPI-based hypervisors (XenServer, XCP-ng) can inject arbitrary key-value pairs into VDI.xenstore_data, a field documented as "generally set by the SM backends on vdi_attach." The field has zero map_keys_roles restrictions, zero write-time validation, and zero sanitization. Injected data persists in the XAPI database and is visible to all API consumers. Downstream systems - backup tools, inventory scanners, orchestration platforms - that read VDI.xenstore_data may trust the values as SM-generated storage metadata. The xe CLI reports this field as read-only, but programmatic API access (Python bindings, JSON-RPC, XenOrchestra) bypasses this CLI restriction entirely.

Vulnerability Description

VDI.xenstore_data is a Map(String, String) field defined with ~qualifier:RW at datamodel.ml:6352-6369. The field is designed as a storage metadata channel - SM drivers generate SCSI identity data, storage type identifiers, and VDI UUIDs that flow to guest xenstore during VBD attach.

A critical architectural distinction limits the impact: the XAPI database field and the SM driver's runtime self.xenstore_data Python attribute are completely independent. The SM driver generates xenstore data fresh in memory during every attach operation and does not read the XAPI database field. Injecting data into the database field does NOT inject data into the live xenstore sm-data/ path.

However, the database field is dangerous because:

  1. Any key-value pair is accepted without validation
  2. The data persists indefinitely in the XAPI database
  3. Downstream API consumers have no way to distinguish SM-generated entries from vm-admin-injected entries
  4. The data propagates during snapshot, clone, introduce, and pool join operations

The xe CLI restriction (Error: Map field 'xenstore-data' is read-only.) is not a security boundary - it is a CLI-level display decision. The underlying XAPI API exposes full read-write access.

Root Causes

  1. Missing RBAC protection. VDI.xenstore_data has zero map_keys_roles entries. Unlike VDI.other_config which has entries for folder and XenCenter.CustomFields.*, this field has no per-key restrictions.

  2. No write-time validation. Any key name and any value are accepted. There is no whitelist of valid keys, no format validation, and no content sanitization.

  3. SM-internal field exposed to users. The field is documented as "generally set by the SM backends" but has ~qualifier:RW, generating write methods accessible to vm-admin.

  4. No provenance tracking. There is no mechanism to distinguish between entries written by SM drivers and entries written by API users.

Affected Systems

Directly Affected

Indirectly Affected

Exploitation Scenarios

Scenario Impact Pre-conditions Status
Arbitrary key injection Inject attacker-controlled metadata into XAPI database vm-admin, API client (not CLI) Confirmed (live host)
Downstream consumer confusion Backup or inventory tools trust injected data as SM-generated vm-admin, downstream consumers reading VDI records Source-traced
Metadata persistence Poisoned data survives VM restarts, VDI operations vm-admin Confirmed (live host)

Chaining Analysis

Detection

Remediation

Short-Term Mitigations

Long-Term Fix

Restrict write access. Change write role to _R_POOL_ADMIN or _R_LOCAL_ROOT_ONLY since the field is designed for SM-internal use. There is no legitimate reason for vm-admin to write to this field.

Add key validation. If the field must remain user-writable, validate that keys match expected SM patterns. Reject unknown keys.

Change to DynamicRO. Change the field from ~qualifier:RW to ~qualifier:DynamicRO to eliminate auto-generated write methods entirely.

Upstream patches exist. They are held privately pending coordinated disclosure.

Disclosure

Disclosure:

References

Credits

Discovered and reported by Jakob Wolffhechel, Moksha.

Jakob Wolffhechel · Moksha · Copenhagen
jakob@wolffhechel.dk · +45 3170 7337
Published 2026-04-24 08:00 CEST · cna.moksha.dk · shittrix.moksha.dk