Back to Intelligence

CVSS 10.0 LXD and MicroCloud TLS Authentication Bypass: Detection and Remediation Guide

SA
Security Arsenal Team
November 1, 2026
15 min read

Security teams running Canonical's LXD or MicroCloud are facing a maximum-severity authentication bypass that shatters the trust model of their virtualization infrastructure. A CVSS 10.0 flaw allows a remote attacker to authenticate to the LXD API as a fully trusted client — without possessing that client's private key. The only prerequisites are network access to the HTTPS API endpoint (default TCP/8443) and possession of the trusted client's public certificate, which is frequently obtainable. This is not a theoretical risk: successful exploitation grants the attacker complete control over the cluster, every container, and every virtual machine running on it. If your organization uses LXD for production virtualization, CI/CD runners, or edge compute, treat this as an emergency change event.

What Happened

Canonical disclosed a critical vulnerability in the TLS client-certificate authentication implementation used by LXD (the Linux container and VM manager) and MicroCloud (the lightweight clustered cloud built on LXD, MicroCeph, and MicroOVN). The flaw exists in how the server validates client certificates during the mutual TLS handshake. Under specific conditions, the server fails to properly verify that the connecting client holds the private key corresponding to the presented public certificate. As a result, an attacker who has obtained a trusted client's public certificate — which is, by design, not secret — can complete the TLS handshake and be authenticated as that trusted identity.

Once authenticated, the attacker inherits the full privileges of the impersonated client. In a default LXD deployment, trusted clients are effectively root-equivalent: they can create, modify, start, stop, and delete instances; mount host filesystems into containers; execute arbitrary commands inside any instance; and pivot to the underlying host. In a MicroCloud deployment, the blast radius extends to the entire clustered infrastructure, including storage and software-defined networking. Given the central role LXD plays in Ubuntu-based virtualization, Ubuntu Server deployments, and Canonical's edge and cloud portfolio, the exposure surface is significant.

Technical Analysis

Affected Products and Platforms

  • LXD: All supported LTS and feature release tracks prior to the patched versions (see Remediation below). LXD is deployed directly on Ubuntu Server, Ubuntu Desktop, and other Linux distributions via snap or deb packages. It is also embedded in MicroCloud and MicroCluster deployments.
  • MicroCloud: All releases prior to the patched version. MicroCloud orchestrates LXD, MicroCeph, and MicroOVN into a clustered private cloud, meaning the vulnerability propagates across the entire cluster management plane.
  • Platforms: Any Linux host running LXD, including bare-metal servers, edge appliances, CI/CD build infrastructure, and cloud images. Ubuntu 20.04 LTS, 22.04 LTS, and 24.04 LTS are the most common deployment bases.

CVSS Score and Severity

The vulnerability has been assigned a CVSS v3.1 score of 10.0 (Critical). The vector characteristics are consistent with the following assessment:

  • Attack Vector: Network — exploitation requires only network reachability to the LXD API.
  • Attack Complexity: Low — no special conditions or extensive preparation beyond obtaining the public certificate.
  • Privileges Required: None — the attacker does not need any prior authentication.
  • User Interaction: None — exploitation is fully automated.
  • Scope: Changed — compromise of the API grants control over the underlying host and all managed instances.
  • Confidentiality, Integrity, Availability: High — full read/write/control over virtualized workloads.

How the Vulnerability Works

The flaw resides in the TLS handshake and certificate validation logic within the LXD daemon (lxd). LXD supports multiple authentication methods, including TLS client certificates. When a client connects, it presents a certificate; the server checks whether that certificate's fingerprint exists in its trust store (/var/snap/lxd/common/lxd/server.crt on the server side, and the trusted certificate list maintained in the LXD database). In the vulnerable code path, the server accepts the presented certificate as proof of identity without requiring cryptographic proof of possession of the corresponding private key. This typically manifests when the TLS stack is configured to request but not mandate client certificate verification, or when the application layer incorrectly short-circuits the verification callback.

The attack chain from a defensive perspective is:

  1. Reconnaissance: The attacker identifies exposed LXD API endpoints (default TCP/8443) via internet scanning (Shodan, Censys) or internal network enumeration.
  2. Certificate Acquisition: The attacker obtains a trusted client's public certificate. This is far easier than it sounds — public certificates are frequently stored in version control, configuration management repositories, shared documentation, or endpoint file systems (~/.config/lxc/client.crt on administrative workstations).
  3. Handshake Bypass: The attacker initiates a TLS connection to the LXD API and presents the trusted certificate. Due to the verification flaw, the server completes the handshake and establishes an authenticated session.
  4. Post-Exploitation: The attacker now has full API access as the trusted client. Typical actions include creating privileged containers (lxc launch ubuntu:22.04 priv -c security.privileged=true), mounting the host filesystem (lxc config device add priv host disk source=/ path=/host), executing commands (lxc exec priv -- bash), and extracting cloud-init credentials or SSH keys from instances.

Exploitation Status

At the time of publication, proof-of-concept exploit code has been made available, and the technical details are public. While there are not yet widespread reports of in-the-wild exploitation, the combination of a CVSS 10.0 score, public technical analysis, and the high value of virtualization infrastructure makes exploitation highly probable in the near term. Defenders should operate under the assumption that internet-facing LXD instances are being actively probed.

Detection & Response

The following detections are designed for SOC teams ingesting Linux host telemetry (Sysmon for Linux, auditd, journald) and network logs into Microsoft Sentinel or a Sigma-compatible SIEM.

Sigma Rules

YAML
---
title: LXD API TLS Handshake from Untrusted Source
id: 7c3f1a82-9e4b-4d67-bc12-3e5a8f901234
status: experimental
description: Detects TLS connections to the LXD API port from sources that are not expected LXD clients. May indicate reconnaissance or exploitation of the certificate verification bypass.
references:
  - https://thehackernews.com/2026/11/critical-lxd-and-microcloud-flaw-cvss.html
author: Security Arsenal
date: 2026/11/15
tags:
  - attack.initial_access
  - attack.t1190
logsource:
  category: network_connection
  product: linux
detection:
  selection:
    DestinationPort: 8443
    Initiated: 'true'
  filter_localhost:
    SourceIp:
      - '127.0.0.1'
      - '::1'
  condition: selection and not filter_localhost
falsepositives:
  - Legitimate LXD client connections from admin workstations
  - Cluster member traffic in MicroCloud deployments
level: medium
---
title: LXD Client Certificate File Access by Non-LXD Process
id: 4d8b2c91-5f3a-4e78-bd21-9c0e7f2a4b5c
status: experimental
description: Detects access to LXD client certificate files by processes other than the LXD client (lxc) or legitimate configuration management tools. Attackers may steal public certificates to facilitate impersonation.
references:
  - https://thehackernews.com/2026/11/critical-lxd-and-microcloud-flaw-cvss.html
author: Security Arsenal
date: 2026/11/15
tags:
  - attack.credential_access
  - attack.t1552
logsource:
  category: file_event
  product: linux
detection:
  selection:
    TargetFilename|endswith:
      - '/.config/lxc/client.crt'
      - '/.config/lxc/client.key'
      - '/snap/lxd/common/lxd/server.crt'
  filter_legit:
    Image|endswith:
      - '/lxc'
      - '/lxd'
      - '/ansible'
      - '/puppet'
      - '/chef'
  condition: selection and not filter_legit
falsepositives:
  - Backup software accessing configuration directories
  - Security scanners performing file integrity monitoring
level: high
---
title: LXD Privileged Container Creation via API
id: 2e6a9d14-8c5b-4f39-ae47-1b3d5f7c9e2a
status: experimental
description: Detects the creation of privileged LXD containers or the mounting of host filesystems into containers, which is a common post-exploitation behavior after API compromise.
references:
  - https://thehackernews.com/2026/11/critical-lxd-and-microcloud-flaw-cvss.html
author: Security Arsenal
date: 2026/11/15
tags:
  - attack.privilege_escalation
  - attack.t1611
logsource:
  category: process_creation
  product: linux
detection:
  selection:
    Image|endswith: '/lxc'
    CommandLine|contains:
      - 'security.privileged=true'
      - 'source=/ path=/host'
      - 'config device add'
      - 'launch'
  condition: selection
falsepositives:
  - Legitimate administrative container management
  - DevOps pipelines that intentionally create privileged build containers
level: high

KQL (Microsoft Sentinel / Defender)

The following hunt queries assume Syslog and process execution data is ingested via the Log Analytics agent, AMA, or a CEF forwarder.

KQL — Microsoft Sentinel / Defender
// Hunt 1: LXD API connections from external or unexpected sources
CommonSecurityLog
| where TimeGenerated > ago(7d)
| where DestinationPort == 8443
| where DeviceAction != "Deny"
| extend SourceIP = SourceIP, DestinationIP = DestinationIP
| summarize ConnectionCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, DestinationIP, DeviceName
| order by ConnectionCount desc

// Hunt 2: Access to LXD client certificate files
Syslog
| where TimeGenerated > ago(7d)
| where SyslogMessage has_any ("client.crt", "client.key", "server.crt")
| where SyslogMessage has_any ("lxc", "lxd", "config")
| extend Process = extract(@"(?:process|proc)[=: ]+(\S+)", 1, SyslogMessage)
| extend FilePath = extract(@"(/\S*(?:client|server)\.(?:crt|key))", 1, SyslogMessage)
| where isnotempty(FilePath)
| summarize AccessCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by Computer, Process, FilePath
| order by AccessCount desc

// Hunt 3: LXD container management commands indicating post-exploitation
SecurityEvent
| where TimeGenerated > ago(7d)
| where EventID == 4688
| where Process has "lxc"
| where CommandLine has_any ("launch", "exec", "config device add", "security.privileged")
| extend Host = Computer, User = Account
| summarize ExecutionCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by Host, User, CommandLine
| order by ExecutionCount desc

// Hunt 4: Network connections to LXD API from non-cluster members (requires known cluster IP list)
let LXDClusterIPs = dynamic(["10.0.0.0/8", "172.16.0.0/12"]); // Adjust to your environment
DeviceNetworkEvents
| where TimeGenerated > ago(7d)
| where RemotePort == 8443
| where not(ipv4_is_in_range(RemoteIP, "10.0.0.0/8")) and not(ipv4_is_in_range(RemoteIP, "172.16.0.0/12")) // Example external detection
| summarize ConnectionCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by DeviceName, RemoteIP, InitiatingProcessFileName
| order by ConnectionCount desc

Velociraptor VQL

Use this artifact to hunt across Linux endpoints for evidence of LXD compromise, certificate access, and suspicious container management activity.

VQL — Velociraptor
-- Hunt for suspicious LXD API connections and certificate access
-- Artifact: Linux.LXD.CompromiseHunt

-- Section 1: LXD API connections from non-localhost
SELECT Pid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE CommandLine =~ 'lxc.*(launch|exec|config.*device|security\.privileged)'
   OR Exe =~ '/snap/lxd/.*/bin/lxd'

-- Section 2: Network connections to LXD API port
SELECT Pid, Name, CommandLine, LocalAddress, LocalPort, RemoteAddress, RemotePort, Status
FROM netstat()
WHERE LocalPort == 8443 OR RemotePort == 8443
  AND Status == 'ESTABLISHED'

-- Section 3: File access to LXD certificates (requires auditd or eBPF integration)
SELECT Pid, Name, CommandLine, Exe, Username
FROM pslist()
WHERE CommandLine =~ 'cat|less|more|nano|vi|cp|scp|rsync'
  AND CommandLine =~ 'client\.crt|client\.key|server\.crt'

Remediation Script

The following Bash script identifies LXD installations, checks for vulnerable versions, applies available updates via snap or apt, and restarts the LXD daemon. It also rotates server certificates as a precaution and audits trusted client certificates.

Bash / Shell
#!/bin/bash
# LXD and MicroCloud Critical Vulnerability Remediation Script
# CVE: Refer to Canonical security advisory for specific CVE assignment
# Run as root on all LXD hosts and MicroCloud cluster members

set -euo pipefail

LOGFILE="/var/log/lxd_remediation_$(date +%Y%m%d_%H%M%S).log"
exec > >(tee -a "$LOGFILE") 2>&1

echo "=== LXD/MicroCloud Remediation Script ==="
echo "Date: $(date)"
echo "Host: $(hostname)"
echo

# --- Detection: Check if LXD is installed ---
echo "[*] Checking for LXD installation..."
if command -v snap &> /dev/null && snap list lxd &> /dev/null; then
    LXD_SNAP_VERSION=$(snap list lxd | awk 'NR==2 {print $2}')
    echo "[!] LXD snap detected: version $LXD_SNAP_VERSION"
    LXD_TYPE="snap"
elif command -v lxd &> /dev/null; then
    LXD_DEB_VERSION=$(lxd --version 2>/dev/null || echo "unknown")
    echo "[!] LXD deb detected: version $LXD_DEB_VERSION"
    LXD_TYPE="deb"
else
    echo "[+] LXD not found on this system. Checking for MicroCloud..."
    if command -v snap &> /dev/null && snap list microcloud &> /dev/null; then
        echo "[!] MicroCloud snap detected. LXD is embedded."
        LXD_TYPE="microcloud"
    else
        echo "[+] No LXD or MicroCloud installation found. Exiting."
        exit 0
    fi
fi

# --- Pre-Remediation: Backup configuration ---
echo "[*] Backing up LXD configuration..."
BACKUP_DIR="/var/backups/lxd_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"
if [[ "$LXD_TYPE" == "snap" ]]; then
    cp -r /var/snap/lxd/common/lxd/* "$BACKUP_DIR/" 2>/dev/null || true
elif [[ "$LXD_TYPE" == "deb" ]]; then
    cp -r /var/lib/lxd/* "$BACKUP_DIR/" 2>/dev/null || true
fi
echo "[+] Backup created at $BACKUP_DIR"

# --- Remediation: Apply updates ---
echo "[*] Applying security updates..."
if [[ "$LXD_TYPE" == "snap" ]]; then
    echo "[*] Refreshing LXD snap..."
    snap refresh lxd --channel=latest/stable
    NEW_VERSION=$(snap list lxd | awk 'NR==2 {print $2}')
    echo "[+] LXD snap updated to version $NEW_VERSION"
elif [[ "$LXD_TYPE" == "deb" ]]; then
    echo "[*] Updating LXD via apt..."
    apt-get update
    apt-get install --only-upgrade lxd lxd-client -y
    echo "[+] LXD deb packages updated"
elif [[ "$LXD_TYPE" == "microcloud" ]]; then
    echo "[*] Refreshing MicroCloud snap (includes LXD)..."
    snap refresh microcloud
    echo "[+] MicroCloud snap updated"
fi

# --- Post-Remediation: Verify and restart ---
echo "[*] Restarting LXD daemon..."
if [[ "$LXD_TYPE" == "snap" ]]; then
    snap restart lxd
elif [[ "$LXD_TYPE" == "deb" ]]; then
    systemctl restart lxd
elif [[ "$LXD_TYPE" == "microcloud" ]]; then
    snap restart microcloud
fi

sleep 5

# --- Verification ---
echo "[*] Verifying LXD service status..."
if [[ "$LXD_TYPE" == "snap" ]]; then
    snap services lxd | grep -q active && echo "[+] LXD snap is active" || echo "[-] LXD snap failed to start"
elif [[ "$LXD_TYPE" == "deb" ]]; then
    systemctl is-active lxd && echo "[+] LXD service is active" || echo "[-] LXD service failed to start"
fi

# --- Certificate Rotation (Precautionary) ---
echo "[*] Rotating LXD server certificate (precautionary)..."
read -p "Rotate server certificate? This will disconnect all existing clients. (yes/no): " -r
if [[ $REPLY =~ ^[Yy][Ee][Ss]$ ]]; then
    if [[ "$LXD_TYPE" == "snap" ]]; then
        rm -f /var/snap/lxd/common/lxd/server.crt /var/snap/lxd/common/lxd/server.key
    elif [[ "$LXD_TYPE" == "deb" ]]; then
        rm -f /var/lib/lxd/server.crt /var/lib/lxd/server.key
    fi
    echo "[*] Restarting LXD to generate new certificate..."
    if [[ "$LXD_TYPE" == "snap" ]]; then
        snap restart lxd
    elif [[ "$LXD_TYPE" == "deb" ]]; then
        systemctl restart lxd
    fi
    echo "[+] Server certificate rotated. All clients must re-trust the new certificate."
else
    echo "[*] Skipping certificate rotation."
fi

# --- Audit Trusted Certificates ---
echo "[*] Auditing trusted client certificates..."
if [[ "$LXD_TYPE" == "snap" ]]; then
    LXC_CMD="/snap/bin/lxc"
elif [[ "$LXD_TYPE" == "deb" ]]; then
    LXC_CMD="/usr/bin/lxc"
else
    LXC_CMD="/snap/bin/lxc"
fi

if [[ -x "$LXC_CMD" ]]; then
    echo "[*] Current trusted certificates:"
    $LXC_CMD config trust list || echo "[-] Failed to list trust. Ensure LXD is running."
    echo
    echo "[!] Review the above certificates. Remove any that are unrecognized or no longer needed:"
    echo "    $LXC_CMD config trust remove <fingerprint>"
else
    echo "[-] lxc client not found. Cannot audit trust store."
fi

# --- Network Hardening Check ---
echo "[*] Checking if LXD API is exposed to network..."
if command -v ss &> /dev/null; then
    LISTENING=$(ss -tlnp | grep :8443 || true)
    if [[ -n "$LISTENING" ]]; then
        echo "[!] LXD API is listening on network:"
        echo "$LISTENING"
        echo "[!] RECOMMENDATION: Restrict access via firewall to authorized management IPs only."
        echo "    Example: iptables -A INPUT -p tcp --dport 8443 -s <MGMT_CIDR> -j ACCEPT"
        echo "             iptables -A INPUT -p tcp --dport 8443 -j DROP"
    else
        echo "[+] LXD API is not listening on TCP/8443 or is socket-activated locally."
    fi
fi

echo
echo "=== Remediation Complete ==="
echo "Log file: $LOGFILE"
echo "Next steps:"
echo "1. Verify patched version: $LXC_CMD version"
echo "2. Review trusted certificates: $LXC_CMD config trust list"
echo "3. Restrict network access to TCP/8443"
echo "4. Monitor for suspicious API activity"

Remediation

Immediate Actions (Within 24 Hours)

  1. Patch LXD and MicroCloud: Update to the latest stable release immediately. Canonical has published fixed versions across all supported tracks.

    • LXD snap: sudo snap refresh lxd
    • MicroCloud snap: sudo snap refresh microcloud
    • LXD deb (Ubuntu): sudo apt update && sudo apt install --only-upgrade lxd lxd-client
    • Verify: Run lxd --version and compare against the fixed versions listed in the Canonical Security Notices.
  2. Audit Network Exposure: Determine if the LXD API is reachable from untrusted networks.

    • Run ss -tlnp | grep 8443 on all LXD hosts.
    • If the API is exposed to the internet, immediately place it behind a firewall or VPN.
    • Restrict TCP/8443 to authorized management networks only using iptables, nftables, or security groups.
  3. Audit Trusted Certificates: Review all certificates in the LXD trust store.

    • Execute lxc config trust list on every LXD server and cluster member.
    • Remove any certificates that are unrecognized, expired, or belong to decommissioned systems.
    • Correlate certificate fingerprints with your asset inventory and configuration management database.
  4. Rotate Server Certificates: As a precautionary measure, regenerate the LXD server certificate to invalidate any sessions that may have been established via the bypass.

    • Delete /var/snap/lxd/common/lxd/server.crt and server.key (snap) or /var/lib/lxd/server.crt and server.key (deb).
    • Restart LXD (sudo snap restart lxd or sudo systemctl restart lxd).
    • Redistribute the new server certificate fingerprint to all legitimate clients.

Short-Term Actions (Within 7 Days)

  1. Rotate Client Certificates: If you have any reason to believe client certificates may have been exposed, generate new client certificates and revoke the old ones.

    • On each client: lxc config trust remove <old_fingerprint> on the server, then generate a new client certificate with lxc config trust add.
  2. Enable LXD API Logging: Ensure detailed API request logging is enabled and forwarded to your SIEM.

    • LXD logs API authentication events to the system journal (journalctl -u snap.lxd.daemon or journalctl -u lxd).
    • Configure your log forwarder to capture these events and alert on authentication failures, certificate mismatches, and requests from unexpected source IPs.
  3. Review MicroCloud Cluster Membership: If running MicroCloud, verify that all cluster members are patched and that no unauthorized members have been added.

    • Run microcloud cluster list on all members and compare against your inventory.

Long-Term Hardening

  1. Implement Network Segmentation: Place LXD management APIs on isolated management VLANs. Use firewall rules to enforce strict source IP allow-listing.

  2. Deploy mTLS with External CA: Consider replacing the default LXD certificate trust model with an external certificate authority and short-lived certificates. This reduces the window of exposure if a certificate is compromised.

  3. Monitor for Anomalous Container Activity: Deploy runtime security monitoring (e.g., Falco, Tracee) to detect privileged container creation, host filesystem mounts, and unusual process execution inside LXD instances.

Official References

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.