LXD and MicroCloud CVSS 10: your public certificate is now a password
mutual TLS. the grown-up auth. the thing we tell people to use instead of passwords. and for an unknown number of years, LXD and MicroCloud checked it like a nightclub bouncer who reads every ID in your wallet and lets you in if any of them is on the list. even the one you found on the floor. the sloth has questions, and also a snap refresh to run.
the bug, in sloth speed
LXD’s remote API authenticates clients with mutual TLS. a client is trusted if its certificate sits in the server’s trust store. during the handshake, the client sends a certificate chain, and TLS only proves one thing: the client owns the private key for the first (leaf) certificate. everything after the leaf is decoration the client picked.
per Canonical’s advisory, LXD’s auth logic compared every certificate in the presented chain against the trust store. so an attacker makes their own throwaway cert, staples the victim’s public cert behind it as a fake intermediate, and the server goes “oh hey, it’s you.” the Incus advisory says that in Incus this has been the case since the initial release.
- impact (Canonical): you act as the impersonated client, with access to the cluster and its VMs. if that client is privileged, Canonical says the attacker may gain root access to the host machine.
- MicroCloud bonus round: an attacker who can intercept the public certificate of a member while it joins the cluster can then authenticate as that member.
- Incus’s own write-up goes further for Incus: server certificates come back in every TLS handshake, so appending the server’s own cert granted database gateway access, other members’ certs granted internal cluster access, and the same flaw hit trust store renew and delete paths plus the host to VM agent connection. Canonical’s advisory does not spell those out for LXD, so treat them as “same root cause, check your vendor.”
- CWE-295 (improper certificate validation), CAPEC-475 (signature spoofing by improper validation).
who is actually exposed
good news first: a standalone LXD server does not expose the HTTPS API by default. it talks on a local unix socket until someone sets core.https_address (usually :8443, which means every interface, which means the sloth is already sighing). you are in the blast radius if:
lxc config get core.https_addressreturns anything, and- an attacker can route to that port, and
- you have trusted client certs in the store (the ones you added with
lxc config trust addor join tokens). public certs are not secrets. they sit on laptops, CI runners, ticket attachments, and, for Incus, in API responses to other trusted clients. - MicroCloud and LXD clusters listen on the network by design. that is the whole point of a cluster.

affected and fixed
- CVE record: LXD 4.0.14, 5.0.10, 5.21.8 and 6.9 are listed as affected, up to the fixes. note the 6.x range runs from 6.9 to before 6.10.1, so 6.10.0 is in it too. Canonical tells all LXD and MicroCloud users to update, so the practical rule is: below the fixed floor for your track means patch.
- fixed LXD snaps (Oct 29): 6/stable 6.10.1, 5.21/stable 5.21.9, 5.0/stable 5.0.11, 4.0/stable 4.0.15.
- fixed MicroCloud snaps (Oct 29): 3/stable 3.4.1, 2/stable 2.1.5.
- Ubuntu archive: Ubuntu’s CVE tracker lists the
lxdpackage as not affected (20.04 and older) or not in release (22.04 and newer). LXD ships as a snap these days, so the snap is what you patch. - Incus: everything below 7.6.0 is vulnerable per its advisory. 7.6.0 fixed this plus 17 other security issues, eight of them rated critical in total including this one. we covered one of the earlier Incus bugs in the Incus backup path traversal lab.

what to do today
- patch.
sudo snap refresh lxdandsudo snap refresh microcloud. Canonical said the point releases were rolling out progressively from candidate to stable, so runsnap list lxd microcloudafterward and confirm you are at or above the floor. pinned or held snaps (snap refresh --hold) will not move on their own. - interim mitigation: restrict the listener. neither Canonical nor Incus offers a config workaround. Incus says flatly the only step is restricting network access. bind
core.https_addressto a management interface instead of:8443, and firewall 8443 to known admin and cluster member addresses. if you never use the remote API, unset it. - audit the trust store.
lxc config trust list(on newer LXD,lxc auth identity listtoo). every entry is an identity an attacker could have worn before you patched. delete the dead CI runner, the 2024 contractor, the laptop that was “reimaged.” - rotate what matters. patching closes the hole, it does not tell you who walked through it. for privileged clients on an exposed listener, issue new client certs, add them, then remove the old fingerprints. on MicroCloud, think about whether a join ever happened over a network someone else could watch.
- Incus shops: go to 7.6.0 and read the full list of 18 fixes while you are there.
detection ideas
there is no public exploit to fingerprint, and a successful login looks like a normal mTLS login by a trusted fingerprint. so hunt for behavior, not a signature:
- lifecycle events with odd source addresses.
lxc monitor --type=lifecycle --pretty(or the Loki or syslog forwarding you configured) records a requestor with the protocol, the identity and the source address. a known fingerprint showing up from an IP that has never used it, or from outside your admin range, is your top alert. - trust store churn.
certificate-created,certificate-updatedandcertificate-deletedevents you did not schedule. an attacker wearing a stolen identity would love to add a cert of their own so they can come back after you patch. - instance actions nobody owns: new instances,
exec, file pushes, config changes addingsecurity.privilegedor host disk devices, from a client that usually only reads metrics. - daemon logs:
journalctl -u snap.lxd.daemonaround the times above, and firewall or flow logs for new sources hitting 8443.

sloth take
the funniest part of this bug is that it is not exotic crypto. it is the oldest mTLS mistake in the book: trusting the chain the client handed you instead of the cert the client proved it owns. a public certificate is called public because it is public. if your auth treats it like a secret, it is a password printed on a billboard. credit where due: the fork found it, told upstream, and both shipped fixes within days. now do your part. refresh the snap, kill the :8443 on every interface, and clean out that trust store. the sloth already did, and the sloth does nothing fast.
sources
- Canonical, “Security advisory: Critical vulnerability found in Canonical LXD and MicroCloud” (Ubuntu Discourse, October 2026), GHSA-99jp-jwmc-65p4
- CVE record CVE-2026-112816 (Canonical CNA, published October 30, 2026), with CISA ADP SSVC assessment dated October 30, 2026
- Ubuntu Security, CVE-2026-112816 status page
- Incus security advisory GHSA-xg75-xf37-cph9, “Authentication and authorization bypass through unverified client certificate chains” (October 29, 2026)
- Linux Containers Forum, “Incus 7.6 has been released” (October 30, 2026)
- The Hacker News, “CVSS 10.0 LXD, MicroCloud Flaw Lets Attackers Impersonate Trusted Clients Without a Private Key” (November 1, 2026)
