← Back to Feed CACHED · 2026-10-30 23:16:58 · CACHE_KEY CVE-2026-112816
CVE-2026-112816 · CWE-295 · Disclosed 2026-10-30

Canonical LXD HTTPS listener improper certificate validation trusted-client impersonation

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

Like a bouncer checking only a photocopy of an ID against the club's logo, LXD's HTTPS listener accepts any forged trusted-client certificate chain

CVE-2026-112816 is an improper certificate validation flaw in Canonical LXD's HTTPS listener. Affected versions are 4.0.14, 5.0.10, 5.21.8, and 6.9; fixed in 4.0.15, 5.0.11, 5.21.9, and 6.10.1. An unauthenticated attacker who can reach the LXD API over TLS can present a crafted certificate chain and authenticate as any already-trusted client, gaining full API access to the cluster and managed virtual machines.

Canonical has not published a vendor CVSS score for this record, so there is no vendor baseline to compare against. That absence understates the problem: LXD is a hypervisor/container-host control plane, not a low-value utility. Once the HTTPS listener is enabled and reachable, this is an unauthenticated remote API takeover with cluster-wide and VM-level consequences. We assess it as CRITICAL. The assessment relies on the supplied official CVE record description; no independent live web source was verifiable at analysis time.

"A forged certificate chain on an exposed LXD HTTPS listener hands an unauthenticated attacker the keys to every VM and cluster member."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Reach an exposed LXD HTTPS listener

LXD clusters and remote management often listen on TCP port 8443 or a custom core.https_address. An attacker probes the network for LXD certificate endpoints or identifies a host via internal service discovery. Default LXD uses a local Unix socket, but cluster members and remote dashboard/CLI access often bind to an interface.
Conditions required:
  • Network route to the LXD API
  • core.https_address or cluster.https_address set to a reachable interface
  • TLS port not blocked by host firewall or NGFW
Where this breaks in practice:
  • Default configuration listens only on a Unix socket
  • Most enterprise LXD clusters expose the API only on a dedicated management VLAN
  • Firewall/NSG rules often restrict 8443 to admin jump hosts
Detection/coverage: Network scanners such as Shodan/Censys may identify LXD HTTP APIs on 8443/tcp; internal asset inventory should flag listening LXD nodes.
STEP 02

Forge a trusted-client certificate chain

LXD validates client certificates against a configured trust store. The improper validation allows a crafted chain — one that omits or contradicts intermediate constraints — to be treated as if it were an already trusted client. The attacker does not need to steal a private key; they can generate a malicious chain locally once the listener is identified.
Conditions required:
  • Vulnerable LXD version
  • Attacker can supply an arbitrary certificate chain during TLS client authentication
  • No external TLS-terminating proxy that performs strict client CA validation before LXD
Where this breaks in practice:
  • Requires the attacker to craft a specific chain exploiting the validation logic
  • Fixed in patched versions
  • A TLS-terminating proxy with strict client CA validation may block the chain before it reaches LXD
Detection/coverage: Host-level TLS handshake failures or anomalies may appear in LXD logs if verbose client auth logging is enabled.
STEP 03

Authenticate to LXD API as an arbitrary trusted client

After presenting the crafted chain, the attacker is accepted as an existing trusted client identity. This grants the same privileges as that client, which in most admin configurations includes full management of clusters, storage pools, profiles, containers, and VMs.
Conditions required:
  • Listener runs vulnerable certificate-validation code
  • Trust policy grants the impersonated client admin rights, typical for remote admin certificates
Where this breaks in practice:
  • If the LXD trust store uses per-client granular RBAC, the impersonated identity may be limited
  • Patched versions reject the malformed chain
Detection/coverage: LXD audit logs may record an API login or certificate authentication event that does not match expected client source IPs.
STEP 04

Enumerate and control the cluster and managed workloads

Using the authenticated API, the attacker lists cluster members, storage options, container/VM definitions, and network bridges. They can then create or modify a privileged container profile, attach host paths as disks, or exec into existing privileged workloads to pivot to the underlying host.
Conditions required:
  • Authenticated API session
  • LXD daemon runs with sufficient privilege to create/modify profiles, default for admin
Where this breaks in practice:
  • Strict RBAC or immutable profiles may limit the attacker to a subset of workloads
  • Host-level EDR or kernel hardening may alert on new privileged containers
  • Cluster network segmentation may contain initial node compromise
Detection/coverage: LXD API activity logs show unexpected container/profile creation or exec operations; EDR may flag lxc exec and host filesystem mounts.
STEP 05

Compromise LXD hosts and adjacent systems

From a privileged container with host disk mounts — for example root filesystem attached under /mnt/host — or with security.privileged=true, the attacker can write to host init scripts, add SSH keys, or exploit kernel-mediated escapes to gain host root. Compromise of a cluster member can then propagate using existing LXD trust relationships and shared storage.
Conditions required:
  • Privileged container or profile creation permitted
  • Host filesystem mounts allowed by LXD config
  • No AppArmor/SELinux policy blocking host path access
Where this breaks in practice:
  • LXD defaults to unprivileged containers and AppArmor confinement
  • Some profiles disable host disk mounts or privileged mode
  • Storage/network segmentation may slow lateral movement
Detection/coverage: EDR or auditd may flag creation of a privileged container, host path attach, or modifications under /etc and /root from a container.
03 · Compensating Control

1
CRITICAL 9.3→LOW 2.0
SEVERITY REDUCED
Disable LXD remote HTTPS API if not essential — On each LXD host, unset core.https_address/cluster.https_address or bind to 127.0.0.1; use Unix socket over SSH for management. Deploy within 3 days (noisgate mitigation SLA for CRITICAL). This removes the vulnerable listener from the network path.
2
CRITICAL 9.3→HIGH 7.5
SEVERITY REDUCED
Restrict LXD API to a dedicated management VLAN with jump-host ACLs — If remote API must remain, use firewall or security-group rules to allow only admin jump hosts and LXD cluster members. Deploy within 3 days. This limits the attacker population from arbitrary network to already-compromised admin infrastructure.
3
CRITICAL 9.3→IGNORE 0.0
SEVERITY REDUCED
Upgrade LXD to 4.0.15, 5.0.11, 5.21.9, or 6.10.1 — Apply the actual patch within 90 days (noisgate remediation SLA for CRITICAL). The patched versions reject the crafted chain and eliminate the vulnerability.
4
CRITICAL 9.3→CRITICAL 9.3
Enable LXD API audit logging and alert on unexpected certificate auth or privileged profile changes — Does not stop the attack but reduces dwell time. Configure remote syslog/SIEM for LXD and monitor for unexpected lxc profile create, lxc config device add, and lxc exec events.
What doesn't work
  • Client-side AppArmor profiles on containers do not stop the initial certificate authentication or API takeover; they only limit later container escape.
  • A WAF or typical HTTP inspection cannot evaluate raw TLS client certificate chain validation flaws unless it terminates mTLS with strict independent trust.
  • Restricting the LXD API to the same server VLAN but allowing all servers does not meaningfully reduce risk in a flat data-center network; an attacker with a foothold on one host can still reach the API.
04 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo public exploitation, CISA KEV not listed; no GreyNoise or Shodan IOCs located at assessment time.
PoC availabilityNo public GitHub repo or PocIndex entry for CVE-2026-112816 located; exploitation likely requires a custom crafted chain.
EPSSNot published for this CVE.
KEVNot listed.
CVSS vector (assessed)CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H — scope changed because host cluster/VMs are impacted.
Affected versions4.0.14, 5.0.10, 5.21.8, 6.9; fixed in 4.0.15, 5.0.11, 5.21.9, 6.10.1
ExposureDefault LXD binds to a Unix socket; remote API exposure is uncommon publicly but relevant on management VLANs and backup/cluster networks.
Disclosure date2026-10-30
Reporting researcher/orgNot provided in the official record supplied.
CWECWE-295 Improper Certificate Validation

Sources.

  1. NVD CVE-2026-112816
  2. CVE.org Record
  3. Ubuntu Security CVE-2026-112816
  4. LXD GitHub Releases
  5. LXD REST API Documentation
  6. CWE-295
  7. PocIndex search for CVE-2026-112816
  8. CISA Known Exploited Vulnerabilities Catalog
05 · The Call

Final Verdict
= UNCHANGED to CRITICAL (9.3/10)

Why this verdict

  • Assessed baseline: No vendor CVSS exists; starting from vulnerability properties (unauthenticated remote, low complexity, high CIA impact) aligns with CVSS 9.3–9.8.
  • Role multiplier: LXD is a hypervisor/container control plane. On management VLANs and cluster nodes, full API takeover is fleet- and VM-scale; compromise can reach host root via privileged container profiles. This floors the verdict at CRITICAL under noisgate high-value-role rules.
  • Friction audit: The biggest real-world narrowing is exposure — default LXD does not listen on TCP, and most enterprises bind the API to a management VLAN. That does not break the CRITICAL floor for a hypervisor/container-host role, but it prevents a score of 10.

Why not higher?

Not a 10.0 because the attack requires a reachable HTTPS listener rather than default Unix-socket-only access. Most installations do not expose the API to the public internet, and no active exploitation or public PoC has been observed. A 9.3 reflects an unauthenticated chain-to-cluster takeover on exposed systems with meaningful but not universal reach.

Why not lower?

Cannot be below CRITICAL because the vulnerable component is canonically a high-value hypervisor/container-host role. Successful exploitation yields cluster-wide and VM-level control, with plausible host root via privileged containers. Network reachability alone does not lower the floor under noisgate rules when the affected role is hypervisor-scale.

06 · Verification

Crowdsourced verification payload.

Run on each LXD node as root (or via sudo) from a management shell. Example: sudo bash check_cve_2026_112816_lxd.sh. The script checks the installed LXD version via lxd --version or snap, compares against patched lines, and exits 0 for PATCHED, 1 for VULNERABLE, 2 for UNKNOWN.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# CVE-2026-112816 LXD version check
# Exit 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u

ver_ge() {
  awk -v a="$1" -v b="$2" 'BEGIN{ split(a,av,"."); split(b,bv,"."); for(i=1;i<=3;i++){ av[i]=av[i]+0; bv[i]=bv[i]+0; } if(av[1]>bv[1] || (av[1]==bv[1] && av[2]>bv[2]) || (av[1]==bv[1] && av[2]==bv[2] && av[3]>=bv[3])){ exit 0 } else { exit 1 } }'
  return $?
}

VRAW=""
if command -v lxd >/dev/null 2>&1; then
  VRAW=$(lxd --version 2>/dev/null | awk '{print $1}')
fi
if [ -z "$VRAW" ] && command -v snap >/dev/null 2>&1; then
  VRAW=$(snap list lxd 2>/dev/null | awk '/^lxd /{print $2}' | head -1)
fi
if [ -z "$VRAW" ]; then
  echo "UNKNOWN: LXD version not found"
  exit 2
fi

major=$(echo "$VRAW" | cut -d. -f1)
minor=$(echo "$VRAW" | cut -d. -f2)
case "$major.$minor" in
  4.0)
    patched_floor="4.0.15"
    ;;
  5.0)
    patched_floor="5.0.11"
    ;;
  5.21)
    patched_floor="5.21.9"
    ;;
  6.9|6.10)
    patched_floor="6.10.1"
    ;;
  *)
    if [ "$major" -gt 6 ] || { [ "$major" -eq 6 ] && [ "$minor" -gt 10 ]; }; then
      patched_floor="6.10.1"
    else
      echo "UNKNOWN: series $major.$minor not covered"
      exit 2
    fi
    ;;
esac

if ver_ge "$VRAW" "$patched_floor"; then
  echo "PATCHED: LXD $VRAW >= $patched_floor"
  exit 0
else
  echo "VULNERABLE: LXD $VRAW < $patched_floor"
  exit 1
fi