MOKSHA-2026-0073: SR Destruction Protection Bypass and DoS via SR.other_config indestructible

Advisory IDMOKSHA-2026-0073
Semantic IDSOC-4
Published2026-04-24
CVSS 3.14.9 Medium
CVSS 3.1 VectorAV:N/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:H
CVSS 4.05.1 Medium
CVSS 4.0 VectorAV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
XAPI ObjectSR
XAPI Fieldother_config:indestructible
Entry Rolepool-operator
ResearcherJakob Wolffhechel, Moksha

Affected Products

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

Summary

A pool-operator in XAPI-based hypervisors (XenServer, XCP-ng) can manipulate the indestructible key in SR.other_config to either prevent authorized SR destruction (denial-of-service) or remove destruction protection from a protected SR (security bypass). The assert_sr_not_indestructible function at xapi_sr.ml:433-442 checks for this key before allowing SR.destroy and SR.forget operations. Setting indestructible=true on any SR blocks both operations, requiring direct database manipulation to remove the key. Conversely, removing the key from a legitimately protected SR enables unauthorized destruction. The SR.other_config field has no map_keys_roles entries for infrastructure keys.

Vulnerability Description

SR.other_config is a Map(String, String) field defined at datamodel.ml:4930-4935 with _R_POOL_OP as the minimum write role inherited from the SR class default.

The protection check:

xapi_sr.ml:433-442:
  let assert_sr_not_indestructible ~__context ~sr =
    let oc = Db.SR.get_other_config ~__context ~self:sr in
    if List.mem_assoc "indestructible" oc
       && List.assoc "indestructible" oc = "true" then
      raise (Api_errors.Server_error (Api_errors.sr_indestructible, [Ref.string_of sr]))

This check is enforced before SR.destroy at message_forwarding.ml:5024. The check is a simple string comparison with no RBAC differentiation - the same pool-operator who can set the key can also remove it. This creates two attack vectors:

  1. DoS: Set indestructible=true on any SR. The SR cannot be destroyed or forgotten through normal API operations. Removing the key requires direct database access.

  2. Protection bypass: Remove indestructible=true from a legitimately protected SR (set by a pool-admin for policy reasons). The pool-operator can then proceed to destroy the SR.

Root Causes

  1. Missing RBAC protection. SR.other_config has map_keys_roles entries only for UI keys (folder, XenCenter.CustomFields.*). The indestructible key is writable by any pool-operator.

  2. No RBAC differentiation for destruction protection. The same role that can set indestructible can also remove it, making the protection ineffective against lateral attackers at the same privilege level.

  3. No write-time validation. XAPI accepts any value for the key without checking whether the caller should be allowed to modify SR lifecycle policy.

  4. set_other_config RBAC bypass. The set_other_config method replaces the entire map atomically and bypasses map_keys_roles per-key checks.

Affected Systems

Directly Affected

Indirectly Affected

Exploitation Scenarios

Scenario Impact Pre-conditions Status
SR locking DoS SR cannot be destroyed or forgotten; requires DB-level intervention pool-operator Source-traced
Destruction protection bypass Attacker removes protection from critical SR, enables unauthorized destruction pool-operator Source-traced
Pool cleanup sabotage Set all SRs to indestructible, blocking decommissioning pool-operator Modeled
BOC-1 chain vm-admin locks/unlocks SRs via RBAC collapse vm-admin, BOC-1 Source-traced

Chaining Analysis

Detection

Remediation

Short-Term Mitigations

Long-Term Fix

Add map_keys_roles protection. Restrict the indestructible key to _R_POOL_ADMIN in datamodel.ml. This ensures pool-operators cannot modify SR lifecycle policy.

Separate destruction protection. Move the indestructible flag to a dedicated first-class field with its own RBAC control, rather than relying on an unprotected other_config key.

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