CSIPE

Published

- 14 min read

LXD Trusted a Certificate Without Proof of Its Key


Books by the author

Compare all 5

As an Amazon Associate I earn from qualifying purchases. Buying through these links costs you nothing extra and helps pay for the blog.

A client certificate is public by design. The proof of identity comes from showing that you control its private key. In late October 2026, an authentication bug in LXD, MicroCloud, and Incus broke that connection: the server could recognize a trusted public certificate elsewhere in a client-supplied chain even though the connecting client had never proved possession of that certificate’s key.

At a management API, this broken identity binding can hand an attacker the control plane. Canonical said an unauthenticated attacker who could reach the LXD HTTPS listener could impersonate a trusted client and gain access to the cluster and its managed virtual machines. Depending on the copied identity’s privileges, that access could extend to root on the host (Canonical security advisory).

Control planes, internal tools, Model Context Protocol services, and coding-agent backends share this boundary: authentication must bind the accepted identity to the exact credential the caller proved. Authorization is the separate decision about what that identity may do, regardless of whether the credential resembles a TLS certificate.

Inventory every running daemon, patch it, and confirm the version on every node. Restrict network reachability until that inventory is clean. Then trace the evidence that establishes a caller’s identity into the authorization decision and test whether extra caller-controlled material can change the answer.

What happened between October 28 and October 30

Canonical published its LXD and MicroCloud security advisory on October 28, 2026. The company said the issue had been referred by the Incus project and confirmed in LXD. Fixed LXD and MicroCloud snap releases followed on October 29, while Canonical’s CVE page lists October 30 as the publication date for CVE-2026-112816 (Canonical advisory, Ubuntu CVE record).

The affected component was the HTTPS listener used for remote management. According to Canonical’s CVE description, affected LXD versions could let an unauthenticated attacker authenticate as any trusted client by presenting a crafted certificate chain. The resulting access included the cluster and managed virtual machines (Ubuntu CVE record). The identity failure sat at the management API, a powerful control-plane boundary above the managed workloads.

MicroCloud inherited the same dangerous assumption in a setting where machines form a cluster. Canonical warned that someone able to intercept the public TLS certificate of a joining cluster member could later authenticate as that member. The same advisory gave the practical condition for LXD: the attacker had to be able to reach the HTTPS API and possess the public certificate of a trusted TLS client (Canonical advisory).

Incus published its related advisory on October 29 and identified all releases before 7.6.0 as affected. Version 7.6.0 contained the fix and was released on October 30, according to independent technical reporting that compared the related products and release dates (Incus advisory, Ostorlab analysis). The Incus advisory also said the flawed pattern had existed since that project’s initial release (Incus advisory).

As of November 1, 2026, independent reviews reported no known exploitation. The Cloud Security Alliance research note said CISA’s assessment recorded exploitation as none and that the vulnerability was absent from the Known Exploited Vulnerabilities catalog at the time of review. The Hacker News also reported no evidence of exploitation in the wild (CSA research note, The Hacker News report). That dated finding narrows the known activity through November 1; a reachable control plane still warrants prompt patching.

Mutual TLS, in plain English

Mutual TLS, usually shortened to mTLS, lets both sides of a connection authenticate with certificates. The server presents a certificate to the client, as it does in ordinary HTTPS. The client also presents a certificate to the server. Each certificate contains a public key and identity information, while the matching private key stays with its owner.

A public certificate can be copied, sent, logged, or returned during a connection. Its visibility is expected. Security comes from the private key and from the cryptographic proof produced during the handshake. A client that can create the required signature demonstrates control of the private key associated with the leaf certificate, which is the first certificate in the chain it presents.

A certificate chain carries one key-possession proof: the client proves control of the private key for the leaf, the first certificate in its list. Later certificates normally help a verifier connect that leaf to a certificate authority or another trust anchor, and they remain material supplied by the client (Incus advisory).

Think of the chain as a folder handed over at reception. The first page carries a signature that reception can verify. The later pages provide context for checking who issued what. If reception searches every page for a familiar employee badge and grants access when it finds one, a visitor could insert a photocopy of somebody else’s badge. The genuine signature on page one would prove the visitor controls page one’s key, while the copied badge on page three would prove nothing about the visitor.

That is why the leaf matters. Suppose a service has Alice’s public certificate in its trust store. Alice authenticates by presenting that certificate as the leaf and proving control of Alice’s private key. Public certificates routinely travel across networks, so another caller may know Alice’s certificate. Alice’s private key is required to produce her proof. The certificate matched to Alice must be the same certificate whose private key the handshake proved.

The exact implementation failure

The faulty check iterated over every peer certificate supplied by the client and compared each one with trusted entries. Canonical summarized the defect this way: remote API authentication compared all peer certificates with the trust store even though only the leaf proved ownership of the signing key (Canonical advisory). Once the check found a trusted certificate anywhere in the supplied list, the application could accept the corresponding identity.

That loop let the caller nominate candidate identities by placing certificates after the leaf. Finding any trusted certificate in the supplied chain was enough for a match, although the handshake proved private-key possession only for the leaf identity being accepted.

Ordinary successful-client tests concealed the defect. A legitimate client puts its own certificate first, proves its key, and may follow it with issuer certificates, so the faulty loop still selects the expected identity. The mismatch appears when a different leaf is followed by an unrelated trusted certificate: the loop sees the certificate, but the handshake has proved no possession of its key.

The Incus advisory describes the consequence without requiring an exploit recipe. A reachable client could authenticate as a trusted client by adding that identity’s public certificate to its presented chain without holding the matching private key. The flawed checks covered trusted client, metrics, and server certificates, and could include cluster-member identity (Incus advisory). Canonical’s narrower description confirms the corresponding LXD outcome: authentication as any trusted client and access to managed clusters and virtual machines (Ubuntu CVE record).

Authorization could not recover from the wrong identity. If authentication said the caller was a privileged administrator or cluster member, later policy checks operated on that false premise. In the Incus case, the advisory says cluster-member impersonation bypassed authorization and that the unverified chain could also reach scriptlet-based authorization decisions (Incus advisory). That second path is a reminder that untrusted evidence can corrupt more than the first login check if it is passed deeper into policy code.

Independent analysis of the public Incus fix reports that the patched trust checks consult only the first peer certificate, the leaf whose key possession the handshake established (Ostorlab analysis). Extra certificates may still travel in the message as unauthenticated, client-supplied material; only the key-proven leaf can determine the authenticated identity.

Exposure prerequisites and limits

Network reachability was a necessary condition. Canonical said an attacker had to be able to reach the LXD HTTPS API, and the Incus advisory limited its workaround to restricting the HTTPS listener to trusted hosts (Canonical advisory, Incus advisory). A local-only endpoint kept remote callers outside this attack path while the vulnerable code remained installed; a broadly reachable management address opened the path.

Standalone LXD matters here because its default narrows exposure. Independent technical analysis reports that a standalone daemon serves a local Unix socket by default and binds a network listener only when an administrator configures one. Clusters and remote clients need the network API, so those deployments deserve the first inventory pass (Ostorlab analysis). “LXD installed” and “LXD remotely exposed” are different findings.

The second condition, access to a trusted public certificate, was weak because certificates are meant to be distributed. The Incus advisory notes that server certificates are returned during TLS handshakes. Trusted client certificates may be available to already trusted clients or to servers those clients contact. Canonical separately identified a MicroCloud case in which a joining member’s public certificate could be intercepted (Incus advisory, Canonical advisory).

Impact depended on the impersonated identity. Canonical said a trusted client could gain full access to the cluster and managed virtual machines, with possible root access to the host when the victim identity had sufficient privilege (Ubuntu CVE record, Canonical advisory). The Incus advisory adds product-specific paths involving server identities, cluster traffic, trust-store self-service operations, authorization scriptlets, and host-to-virtual-machine agent connections (Incus advisory). Those paths belong within the documented Incus scope. They show how identity confusion at a management listener can spread across several authorization paths, while LXD deployments require separate confirmation of each path.

Patch every daemon, then verify what is running

Canonical listed fixed LXD snap versions 6.10.1, 5.21.9, 5.0.11, and 4.0.15. The fixed MicroCloud releases were 3.4.1 and 2.1.5, all dated October 29 in the advisory’s release table (Canonical advisory). Incus users need version 7.6.0 or later for this issue (Incus advisory).

Record the package operation, then query the running service on every node. Progressive rollout, held updates, failed restarts, an overlooked member, or a second installation path can leave a live daemon on vulnerable code after the refresh command succeeds. Canonical noted at disclosure time that LXD point releases were moving progressively from candidate to stable, so the reported running version is the completion evidence (Canonical advisory).

A practical response should proceed in this order:

  1. Build the daemon inventory: Find LXD, MicroCloud, and Incus on standalone hosts and every cluster member. Record the product, update channel or package source, installed version, running version, cluster role, and owner.

  2. Map listener reachability: Determine whether each HTTPS API is disabled, local-only, restricted to a management network, exposed through another network device, or reachable from an untrusted segment. Check cluster listener addresses as well as the obvious client API address, because an empty client-facing setting may not describe all network paths (Ostorlab analysis).

  3. Reduce access while work continues: Remove direct untrusted reachability and admit only required administrative hosts and cluster peers. A successful firewall change temporarily reduces exposure while the vulnerable code remains. Give this control an owner and a removal condition.

  4. Install the fixed release: Move each LXD and MicroCloud instance to the fixed release for its channel, or move Incus to 7.6.0 or later. For the disclosed channels, the minimum fixed versions are the versions listed above (Canonical advisory, Incus advisory).

  5. Query every running node: Confirm the service reports a fixed version after the update. Reconcile the results with the inventory and require a fixed result from every member. Resolve mixed-version clusters, failed restarts, and stale processes before declaring remediation complete.

  6. Review the exposure window: For listeners that were reachable from untrusted networks, examine trust entries, cluster membership, management API activity, instance and profile changes, and source addresses against expected administrative behavior. An attacker using an existing identity can leave the trust store without a new entry (Ostorlab analysis).

  7. Escalate based on evidence and asset value: If activity is unexplained or a privileged identity may have been impersonated, follow the organization’s host-compromise process. Assess private keys and other credentials available from the host, and recover sensitive systems according to the established incident plan.

  8. Keep durable closure evidence: Save each node’s reported running version with its update timestamp. Add listener reachability after repair and the review results, with an owner named for each result.

The three completion tests answer different questions. Listener reachability shows whether the affected surface has been blocked. Repair is complete when each node reports a fixed running version; the scoped review covers activity before that repair. The durable record keeps one successful test from concealing unfinished work.

The larger control-plane lesson

Authentication is an evidence pipeline. A caller makes a claim, a protocol proves something about that claim, application code maps the proved value to an identity, and authorization decides what that identity may do. Every handoff needs an explicit contract. If one layer assumes the previous layer proved more than it actually did, later policy can be internally consistent and still grant access to the wrong caller.

CVE-2026-112816 failed at the mapping step. The TLS handshake established control of the leaf’s key. Application code searched a larger caller-controlled collection and selected a trusted identity from it. Authorization then received an identity with stronger meaning than the evidence supported. The fix narrowed identity selection to the certificate backed by the handshake proof (Canonical advisory, Ostorlab analysis).

Coding-agent services need the same evidence boundary. A tool server behind a gateway may receive verified workload identity or token claims beside caller-supplied headers and raw request metadata; policy must consume the verified principal without letting those adjacent fields redefine it. An agent runner has the same obligation when a signed job envelope points to an unsigned repository, branch, or tenant value.

The review question should be concrete: Which exact value did the verifier prove, and is that exact value the one authorization consumes? A diagram helps when the answer crosses libraries or services. Mark the trust boundary, label verified and unverified fields, show where account lookup occurs, and follow the resulting principal into every privileged operation.

A typed authentication result should preserve provenance by separating the verified principal from supporting caller data. Policy code receives the principal through its normal interface; reaching a loose certificate array, generic claim map, or other raw input requires an explicit, conspicuous action. This structure bounds the review problem: the proved identity is easy to follow, and any use of caller-supplied material is visible, while logic bugs remain possible.

Authorization still needs its own boundaries. Canonical’s advisory ties impact to the privilege of the impersonated client, and the Incus advisory describes especially broad consequences for server and cluster identities (Canonical advisory, Incus advisory). If everyday automation holds a full control-plane identity, any authentication error inherits that reach. Narrow identities for read-only monitoring, deployment, image management, and cluster operations reduce what one mistaken mapping can authorize.

The Secure Harness develops this model in its chapter on building secure MCP services: authenticate the caller from evidence the protocol proved, then authorize that identity for a narrow set of tools and resources. Larger agent systems make that discipline more important because one unsupported assumption may travel across several components before producing an unsafe action.

Bind identity to the proved key

For CVE-2026-112816, start with systems where the affected HTTPS API was reachable and a suitable trusted public certificate was obtainable. Their management APIs could select an identity from the supplied chain even though the connection proved key possession only for the leaf (Canonical advisory, Incus advisory). Standalone LXD kept its network listener disabled by default, and the supplied reporting described no known exploitation through November 1 (Ostorlab analysis, CSA research note).

Install the fixed LXD or MicroCloud release for the relevant channel, or Incus 7.6.0 or later. Verify every node’s running version and restrict untrusted access until those results are complete. Review the exposure window for reachable privileged management endpoints. In code, bind identity to the leaf whose private-key possession the protocol proved and keep authorization separate.

Subscribe to the newsletter for more practical security analysis for developers. It is one email per month.

Sources