MOKSHA-2026-0086: License Expiry Manipulation via Host.license_params expiry

Advisory IDMOKSHA-2026-0086
Semantic IDLPC-2
Published2026-04-24
CVSS 3.12.3 Low
CVSS 3.1 VectorAV:L/AC:L/PR:H/UI:N/S:U/C:N/I:L/A:N
CVSS 4.04.6 Medium
CVSS 4.0 VectorAV:L/AC:L/AT:N/PR:H/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
XAPI ObjectHost
XAPI Fieldlicense_params:expiry
Entry Rolelocal root (not accessible via XAPI network API)
ResearcherJakob Wolffhechel, Moksha

Affected Products

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

Summary

An attacker with root access on an XAPI-based hypervisor host (XenServer, XCP-ng) can set the expiry key in Host.license_params to "never" or a far-future date, preventing license expiry enforcement and suppressing expiry alerts. The license_check.get_expiry_date function at license_check.ml:28-37 reads the expiry value and treats "never" as no expiration. The Host.license_params field has the strongest access control in the XAPI RBAC system: _R_LOCAL_ROOT_ONLY with pool_internal:true. Like LPC-1, this is a license compliance issue requiring local root - an attacker at that privilege level already has full system control.

Vulnerability Description

Host.license_params is a Map(String, String) field defined at datamodel_host.ml:3055-3059 with DynamicRO qualifier. The sole write method (set_license_params) requires _R_LOCAL_ROOT_ONLY and is not exposed via the external API.

The expiry key is consumed by two systems:

License check gate (license_check.ml:28-47):

license_check.get_expiry_date reads "expiry" from license_params
    |
    v
"never" -> no expiry (VM operations proceed)
date string -> parsed via Clock.Date.of_iso8601
    |
    v
license_check.check_expiry compares against current time
    |
    v
If expired -> raises license_expired API error
    |
    v
Called before VM operations (license_check.vm at line 49-52)

Daily license check daemon (daily_license_check.ml:27-35):

daily_license_check.get_info_from_db reads license_params
    |
    v
Checks expiry dates against current time + 30 day warning window
    |
    v
Generates license_expires_soon or license_expired alerts

An attacker with root access can modify the XAPI database to set expiry="never" or expiry="2099-12-31T23:59:59Z". This prevents the license check gate from blocking VM operations and suppresses the daily license expiry alerts.

Root Causes

  1. No integrity verification. XAPI does not verify that the expiry value was set by the legitimate v6d license daemon. Database modification is accepted without authentication.

  2. "never" as valid expiry. The license_check.ml code treats "never" as a valid expiry value, which is the intended behavior for perpetual licenses but also the simplest manipulation target.

  3. Root access prerequisite. The sole attack path requires local root, which already grants full system control.

Affected Systems

Directly Affected

Indirectly Affected

Exploitation Scenarios

Scenario Impact Pre-conditions Status
Expiry set to "never" License never expires, expiry alerts suppressed Local root on host Source-traced (theoretical)
Expiry set to far future Expiry enforcement delayed indefinitely Local root on host Source-traced
BOC-1 chain vm-admin gains root via BOC-1, modifies expiry in XAPI DB vm-admin, BOC-1 Source-traced

Chaining Analysis

Detection

Remediation

Current State (Adequate)

The current security posture is adequate:

  1. Write access is maximally restricted (_R_LOCAL_ROOT_ONLY + pool_internal)
  2. The field is DynamicRO - no auto-generated map mutation methods
  3. Expiry values are set internally by the v6d license daemon

Optional Hardening

Add integrity verification. Sign license_params data so XAPI can verify it was produced by the legitimate v6d daemon.

Add database integrity checks. Verify that license_params values have not changed between XAPI restarts without a corresponding v6d daemon update.

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