Contents
LXD’s remote API authenticated clients with mutual TLS and a trust store of pinned client certificates. The server took the certificate chain a client presented, compared every certificate in it against the trust store, and accepted the client if any of them matched. Canonical’s advisory describes the consequence: only the leaf certificate proves possession of a private key, so an attacker can put a trusted client’s public certificate behind their own and be treated as that client. The CVE is CVE-2026-112816 and it is scored 10.0.
The same flaw was reported by the Incus project, an LXD fork, and fixed there in 7.6.0. Incus’s advisory says it has existed since the initial release.
What a handshake proves
In a TLS handshake the client sends a certificate chain and then signs the handshake transcript with the private key matching the first certificate, the leaf. The server verifies that signature against the leaf’s public key. That is the only possession proof in the exchange.
Every other certificate in the message is just bytes the client chose to send. Certificates are public by design, so anyone who has seen a trusted client’s certificate can include it. If the server’s logic is “is any certificate in this chain in my trust store,” the attacker sends:
- their own self-generated certificate as the leaf, which they can sign with, and
- the victim’s public certificate behind it.
The handshake succeeds because the attacker holds the leaf key. The trust check then finds the victim’s certificate in the chain and attributes the connection to the victim. Both advisories describe exactly this.
The correct rule is narrower: after the handshake, the identity is the leaf certificate (or, if you use a CA, the chain that verifies up to a CA you trust, with the leaf as the subject). Anything else in the chain is evidence, not identity.
Why this one reaches further than it looks
The Incus advisory lists more than client impersonation. According to it, the same unverified chain was used for server certificates and metrics certificates, and was passed to the authorization scriptlet, so scriptlet-based decisions could be influenced. It says this applies even to token or OIDC clients, because they can present an arbitrary certificate during the handshake. The advisory also lists the host-to-VM agent connection as affected.
The server-certificate case needs the least preparation. A server sends its certificate in every handshake, so an attacker does not need to have observed a client. The advisory says appending it grants access to the database gateway and, on clusters, internal cluster access. I have not seen the code, so I cannot say more about those paths than the advisory does.
For MicroCloud, Canonical says an attacker who captures the public certificate of a member joining the cluster can authenticate as that member. Depending on the privileges of the impersonated identity, the result can be root on the host.
Reachability and what to do
A standalone LXD server does not expose the HTTPS API by default. According to the coverage in The Hacker News, it listens only on a local socket unless core.https_address is set. If you set that to join a cluster, to manage remotely, or to feed a metrics scraper, you are in scope.
Neither project offers a configuration workaround. Incus says to restrict network access to the listener and upgrade. Canonical says to update. The fixed versions in Canonical’s table, all dated 2026-10-29:
| Product | Channel | Fixed |
|---|---|---|
| LXD | 6/stable | 6.10.1 |
| LXD | 5.21/stable | 5.21.9 |
| LXD | 5.0/stable | 5.0.11 |
| LXD | 4.0/stable | 4.0.15 |
| MicroCloud | 3/stable | 3.4.1 |
| MicroCloud | 2/stable | 2.1.5 |
Canonical notes the LXD point releases are moving from candidate to stable progressively, so confirm with snap list lxd rather than assuming snap refresh got you there. For Incus the fixed release is 7.6.0. The Hacker News article reports that CISA’s assessment dated October 30 says the flaw is not known to be exploited, and that no working exploit has been published.
One consequence of the design is that rotating certificates is part of the remediation thinking, not a substitute for patching. Public certificates are not secrets, so an attacker who could reach the listener before you patched did not need to steal anything. I would treat the exposure window as unbounded for any host whose API was reachable from untrusted networks, and review trust store entries on those hosts, since the Incus advisory notes entries can be renewed or deleted through self-service paths.
Check your own mTLS code
You may not run LXD, but the pattern is common in hand-written services, so it is worth a grep. In Go, tls.Config with ClientAuth: tls.RequestClientCert asks for a certificate but does not verify it, which matches the Incus advisory’s wording that the listener “requests client certificates but does not verify them.” That setting is legitimate when you do your own verification afterwards. It is only safe if that verification looks at the right certificate.
Things to check:
- Does the code iterate over
r.TLS.PeerCertificatesorConnectionState.PeerCertificatesand test each one against a pin list? Test onlyPeerCertificates[0], the leaf, because that is the one the handshake proved. - If you rely on a CA, are you calling
Verifywith the intermediates supplied as untrustedIntermediatesand a pool of trusted roots, rather than treating chain membership as trust? - Do any downstream authorization hooks receive the whole chain as an identity attribute? Those can be steered by the client in the same way the scriptlet was.
The first item is my reading of how the vulnerable logic would look in Go, based on the advisories’ description. Neither advisory publishes the vulnerable code, so I am not claiming that this is what LXD’s source contained.
Sources
- Canonical: Critical vulnerability found in Canonical LXD and MicroCloud. Mechanism, MicroCloud impact, fixed versions and dates.
- Incus advisory GHSA-xg75-xf37-cph9. Extended impact, workaround, fixed in 7.6.0.
- The Hacker News coverage. Default listener behaviour and the CISA assessment, which I have not checked at the source. I did not read the Ubuntu CVE page or the Incus 7.6 release notes.
- The Go review checklist is my own interpretation, not taken from either advisory.