CVE-2024-6156
lxd CA certificate sign check bypass
Mark Laing discovered that LXD's PKI mode, until version 5.21.2, could be bypassed if the client's certificate was present in the trust store.
Attack profile
How easy it is to exploit
- Attack vector
- Local
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- Low
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
3.8
Mark Laing discovered that LXD's PKI mode, until version 5.21.2, could be bypassed if the client's certificate was present in the trust store.
- Record
CVE-2024-6156- CVSS 3.1
- 3.8 Low
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N - Weakness
- CWE-295
- Updated
- 2026-11-02
EUVDEUVD-2024-3419
3.8
Mark Laing discovered that LXD's PKI mode, until version 5.21.2, could be bypassed if the client's certificate was present in the trust store.
- Record
EUVD-2024-3419- CVSS 3.1
- 3.8 Low
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-4c49-9fpc-hc3v
3.8
lxd CA certificate sign check bypass
Summary
If a server.ca file is present in LXD_DIR at LXD start up, LXD is in "PKI mode". In this mode, only TLS clients that have a CA-signed certificate should be able to authenticate with LXD.
We have discovered that if a client that sends a non-CA signed certificate during the TLS handshake, that client is able to authenticate with LXD if their certificate is present in the trust store.
- The LXD Go client (and by extension lxc) does not send non-CA signed certificates during the handshake.
- A manual client (e.g. cURL) might send a non-CA signed certificate during the handshake.
Versions affected
LXD 4.0 and above.
Details
When PKI mode was added to LXD it was intended that all client and server certificates must be signed by the certificate authority (see https://github.com/canonical/lxd/pull/2070/commits/84d917bdcca6fe1e3191ce47f1597c7d094e1909).
In PKI mode, the TLS listener configuration is altered to add the CA certificate but the ClientAuth field of tls.Config is not changed. The ClientAuth field is set to tls.RequestClientCert, which configures the TLS connection to request a certificate from the client, but not require one. This is necessary because untrusted requests are allowed for some endpoints.
If a client certificate is present in the trust store before PKI mode is enabled, calls to LXD using that certificate fail when using the Go client for LXD. I believe that what is happening is as follows:
- During the TLS handshake, the server requests a certificate from the client. The server includes in it's request a list of acceptable CAs.
- The go client receives the request from the server, but does not have any certificates that match what the server requires, and so does not send any.
- The server considers the handshake complete because it does not absolutely require the client certificate (see above).
- In the
(*Daemon).Authenticatemethod, when checking for TLS clients, there are noPeerCertificatesin the request. Soutil.CheckTrustStateis never called and the request is denied.
Importantly, the above does not apply if the client sends a certificate during the handshake anyway. If this occurs and the certificate is present in the trust store, the request is trusted and is allowed to continue. It is possible to do this using cURL*.
PoC
The follow snippet demonstrates the vulnerability:
# Install/initialize LXD
$ snap install lxd --channel 5.21/stable
$ lxd init --auto
$ lxc config set core.https_address=127.0.0.1:8443
# Add a certificate to the trust store before enabling PKI.
$ token="$(lxc config trust add --name ca-test --quiet)"
$ lxc remote add tls "${token}"
# Use easyrsa for configuring CA: https://github.com/OpenVPN/easy-rsa
$ cp -R /usr/share/easy-rsa "/tmp/pki"
$ export EASYRSA_KEY_SIZE=4096
$ cd /tmp/pki
$ ./easyrsa init-pki
$ echo "lxd" | ./easyrsa build-ca nopass
$ cp pki/ca.crt /var/snap/lxd/common/lxd/server.ca
# Restart daemon.
$ systemctl reload snap.lxd.daemon
# Using curl with the client certificate we expect a 403 Forbidden response.
# Instead we get a 200 OK and we are able to view the response body.
$ cat ~/snap/lxd/common/config/client.crt ~/snap/lxd/common/config/client.key > ~/snap/lxd/common/config/client.pem
$ curl -s --cert ~/snap/lxd/common/config/client.pem --cacert /var/snap/lxd/common/lxd/server.crt https://127.0.0.1:8443/1.0" | jq '.metadata.config."core.https_address"'
Impact
I believe this has a low impact for the following reasons:
- PKI mode is unlikely to have a large user base.
- PKI is likely to be configured at start up without any previous certificates in the trust store.
- Authentication is not bypassed entirely, the client certificate must already be trusted.
Notes
- I am not certain why cURL sends the certificate during the handshake but we can see it in the logs:
* Trying 127.0.0.1:8443...
% Total % Received % Xferd Average Speed Time Time Time Current
…
- Record
GHSA-4c49-9fpc-hc3v- CVSS 3.1
- 3.8 Low
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N - Weakness
- CWE-295
- Updated
- 2026-11-02
NVD
3.8
Mark Laing discovered that LXD's PKI mode, until version 5.21.2, could be bypassed if the client's certificate was present in the trust store.
- Record
CVE-2024-6156- CVSS 3.1
- 3.8 Low
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N - Weakness
- CWE-295
- Updated
- 2026-11-02
OSV
3.8
Mark Laing discovered that LXD's PKI mode, until version 5.21.2, could be bypassed if the client's certificate was present in the trust store.
- Record
CVE-2024-6156- CVSS 3.1
- 3.8 Low
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N - Updated
- 2026-11-02
OSVDEBIAN-CVE-2024-6156
3.8
Mark Laing discovered that LXD's PKI mode, until version 5.21.2, could be bypassed if the client's certificate was present in the trust store.
- Record
DEBIAN-CVE-2024-6156- CVSS 3.1
- 3.8 Low
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N - Updated
- 2026-11-02
Show 4 moreShow less
OSVGHSA-4c49-9fpc-hc3v
3.8
lxd CA certificate sign check bypass
Summary
If a server.ca file is present in LXD_DIR at LXD start up, LXD is in "PKI mode". In this mode, only TLS clients that have a CA-signed certificate should be able to authenticate with LXD.
We have discovered that if a client that sends a non-CA signed certificate during the TLS handshake, that client is able to authenticate with LXD if their certificate is present in the trust store.
- The LXD Go client (and by extension lxc) does not send non-CA signed certificates during the handshake.
- A manual client (e.g. cURL) might send a non-CA signed certificate during the handshake.
Versions affected
LXD 4.0 and above.
Details
When PKI mode was added to LXD it was intended that all client and server certificates must be signed by the certificate authority (see https://github.com/canonical/lxd/pull/2070/commits/84d917bdcca6fe1e3191ce47f1597c7d094e1909).
In PKI mode, the TLS listener configuration is altered to add the CA certificate but the ClientAuth field of tls.Config is not changed. The ClientAuth field is set to tls.RequestClientCert, which configures the TLS connection to request a certificate from the client, but not require one. This is necessary because untrusted requests are allowed for some endpoints.
If a client certificate is present in the trust store before PKI mode is enabled, calls to LXD using that certificate fail when using the Go client for LXD. I believe that what is happening is as follows:
- During the TLS handshake, the server requests a certificate from the client. The server includes in it's request a list of acceptable CAs.
- The go client receives the request from the server, but does not have any certificates that match what the server requires, and so does not send any.
- The server considers the handshake complete because it does not absolutely require the client certificate (see above).
- In the
(*Daemon).Authenticatemethod, when checking for TLS clients, there are noPeerCertificatesin the request. Soutil.CheckTrustStateis never called and the request is denied.
Importantly, the above does not apply if the client sends a certificate during the handshake anyway. If this occurs and the certificate is present in the trust store, the request is trusted and is allowed to continue. It is possible to do this using cURL*.
PoC
The follow snippet demonstrates the vulnerability:
# Install/initialize LXD
$ snap install lxd --channel 5.21/stable
$ lxd init --auto
$ lxc config set core.https_address=127.0.0.1:8443
# Add a certificate to the trust store before enabling PKI.
$ token="$(lxc config trust add --name ca-test --quiet)"
$ lxc remote add tls "${token}"
# Use easyrsa for configuring CA: https://github.com/OpenVPN/easy-rsa
$ cp -R /usr/share/easy-rsa "/tmp/pki"
$ export EASYRSA_KEY_SIZE=4096
$ cd /tmp/pki
$ ./easyrsa init-pki
$ echo "lxd" | ./easyrsa build-ca nopass
$ cp pki/ca.crt /var/snap/lxd/common/lxd/server.ca
# Restart daemon.
$ systemctl reload snap.lxd.daemon
# Using curl with the client certificate we expect a 403 Forbidden response.
# Instead we get a 200 OK and we are able to view the response body.
$ cat ~/snap/lxd/common/config/client.crt ~/snap/lxd/common/config/client.key > ~/snap/lxd/common/config/client.pem
$ curl -s --cert ~/snap/lxd/common/config/client.pem --cacert /var/snap/lxd/common/lxd/server.crt https://127.0.0.1:8443/1.0" | jq '.metadata.config."core.https_address"'
Impact
I believe this has a low impact for the following reasons:
- PKI mode is unlikely to have a large user base.
- PKI is likely to be configured at start up without any previous certificates in the trust store.
- Authentication is not bypassed entirely, the client certificate must already be trusted.
Notes
- I am not certain why cURL sends the certificate during the handshake but we can see it in the logs:
* Trying 127.0.0.1:8443...
% Total % Received % Xferd Average Speed Time Time Time Current
…
- Record
GHSA-4c49-9fpc-hc3v- CVSS 3.1
- 3.8 Low
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N - Weakness
- CWE-295
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2024-6156
3.8
Mark Laing discovered that LXD's PKI mode, until version 5.21.2, could be bypassed if the client's certificate was present in the trust store.
- Record
UBUNTU-CVE-2024-6156- CVSS 3.1
- 3.8 Low
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N - Updated
- 2026-11-02
OSVGO-2024-3312 No score
CA certificate sign check bypass in github.com/canonical/lxd
CA certificate sign check bypass in github.com/canonical/lxd
- Record
GO-2024-3312- Updated
- 2026-11-02
OSVopenSUSE-SU-2024:14567-1 No score
govulncheck-vulndb-0.0.20241209T183251-1.1 on GA media
These are all security issues fixed in the govulncheck-vulndb-0.0.20241209T183251-1.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2024:14567-1- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
github.com/canonical/lxdGo |
before 0.0.0-20240708073652-5a492a3f0036 | 0.0.0-20240708073652-5a492a3f0036 |
incusDebian:13 |
before 6.0.3-1 | 6.0.3-1 |
incusDebian:14 |
before 6.0.3-1 | 6.0.3-1 |
lxdDebian:12 |
All versions, plus listed versions 5.0.2+git20231211.1364ae4-15.0.2+git20231211.1364ae4-25.0.2+git20231211.1364ae4-35.0.2+git20231211.1364ae4-45.0.2+git20231211.1364ae4-5 Show 12 moreShow less5.0.2+git20231211.1364ae4-65.0.2+git20231211.1364ae4-75.0.2+git20231211.1364ae4-85.0.2+git20231211.1364ae4-95.0.2-55.0.2-5+deb12u15.0.2-5+deb12u25.0.2-5+deb12u35.0.2-5+deb12u45.0.2-5+deb12u55.0.2-5+deb12u65.0.2-6 |
None known |
lxdDebian:13 |
All versions, plus listed versions 5.0.2+git20231211.1364ae4-95.0.2+git20231211.1364ae4-9+deb13u15.0.2+git20231211.1364ae4-9+deb13u25.0.2+git20231211.1364ae4-9+deb13u35.0.2+git20231211.1364ae4-9+deb13u45.0.2+git20231211.1364ae4-9+deb13u55.0.2+git20231211.1364ae4-9+deb13u65.0.2+git20231211.1364ae4-9+deb13u7 |
None known |
lxdUbuntu:Pro:16.04:LTS |
All versions, plus listed versions 0.20-0ubuntu40.21-0ubuntu30.21-0ubuntu50.22-0ubuntu10.22-0ubuntu2 Show 45 moreShow less0.23-0ubuntu10.23-0ubuntu20.23-0ubuntu30.24-0ubuntu20.24-0ubuntu30.24-0ubuntu40.25-0ubuntu10.26-0ubuntu20.26-0ubuntu30.27-0ubuntu10.27-0ubuntu22.0.0~beta1-0ubuntu32.0.0~beta1-0ubuntu42.0.0~beta2-0ubuntu12.0.0~beta2-0ubuntu22.0.0~beta3-0ubuntu12.0.0~beta3-0ubuntu22.0.0~beta3-0ubuntu32.0.0~beta3-0ubuntu42.0.0~beta4-0ubuntu12.0.0~beta4-0ubuntu22.0.0~beta4-0ubuntu32.0.0~beta4-0ubuntu42.0.0~beta4-0ubuntu52.0.0~beta4-0ubuntu62.0.0~beta4-0ubuntu72.0.0~rc1-0ubuntu12.0.0~rc1-0ubuntu22.0.0~rc1-0ubuntu32.0.0~rc2-0ubuntu22.0.0~rc2-0ubuntu32.0.0~rc3-0ubuntu12.0.0~rc3-0ubuntu22.0.0~rc3-0ubuntu32.0.0~rc3-0ubuntu42.0.0~rc4-0ubuntu12.0.0~rc5-0ubuntu12.0.0~rc6-0ubuntu12.0.0~rc6-0ubuntu22.0.0~rc7-0ubuntu12.0.0~rc7-0ubuntu22.0.0~rc8-0ubuntu12.0.0~rc8-0ubuntu22.0.0~rc8-0ubuntu32.0.0~rc8-0ubuntu5 |
None known |
lxdUbuntu:Pro:18.04:LTS |
All versions, plus listed versions 2.18-0ubuntu62.19-0ubuntu12.20-0ubuntu32.20-0ubuntu42.21-0ubuntu1 Show 18 moreShow less2.21-0ubuntu22.21-0ubuntu32.21-0ubuntu43.0.0~beta2-0ubuntu33.0.0~beta3-0ubuntu33.0.0~beta5-0ubuntu23.0.0~beta7-0ubuntu13.0.0-0ubuntu13.0.0-0ubuntu23.0.0-0ubuntu33.0.0-0ubuntu43.0.1-0ubuntu1~18.04.13.0.2-0ubuntu1~18.04.13.0.3-0ubuntu1~18.04.13.0.3-0ubuntu1~18.04.23.0.3-0ubuntu1~18.04.2+esm13.0.3-0ubuntu1~18.04.2+esm23.0.3-0ubuntu1~18.04.2+esm3 |
None known |
lxdUbuntu:20.04:LTS |
All versions, plus listed versions 1:0.71:0.81:0.91:0.10 |
None known |
govulncheck-vulndbopenSUSE:Tumbleweed From an advisory covering 21 CVEs |
before 0.0.20241209T183251-1.1 | 0.0.20241209T183251-1.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, facts | ||
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2024-6156 is a low vulnerability (CVSS 3.8) in Canonical Lxd, published December 5, 2024. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.16%, the 5th percentile. Fixed in github.com/canonical/lxd 0.0.0-20240708073652-5a492a3f0036.
References
github.com/canonical/lxd/security/advisories/GHSA-4c49-9fpc-hc3v
cve.org/CVERecord?id=CVE-2024-6156
nvd.nist.gov/vuln/detail/CVE-2024-6156
github.com/canonical/lxd/commit/92468bb60f4f1edf38ff0434414bea4f28afa711
pkg.go.dev/vuln/GO-2024-3312
github.com/advisories/GHSA-4c49-9fpc-hc3v
Show 26 moreShow less
github.com/CVEProject/cvelistV5/tree/main/cves/2024/6xxx/CVE-2024-6156.json
github.com/canonical/lxd
security-tracker.debian.org/tracker/CVE-2024-6156
ubuntu.com/security/CVE-2024-6156
lists.opensuse.org/archives/list/[email protected]/thread/EK3MV2UFLDNRIXIWLVT5CJNSLB2MKFBU
suse.com/security/cve/CVE-2024-10220
suse.com/security/cve/CVE-2024-36620
suse.com/security/cve/CVE-2024-36621
suse.com/security/cve/CVE-2024-36623
suse.com/security/cve/CVE-2024-37820
suse.com/security/cve/CVE-2024-43784
suse.com/security/cve/CVE-2024-45719
suse.com/security/cve/CVE-2024-50948
suse.com/security/cve/CVE-2024-52003
suse.com/security/cve/CVE-2024-52529
suse.com/security/cve/CVE-2024-52801
suse.com/security/cve/CVE-2024-53259
suse.com/security/cve/CVE-2024-53264
suse.com/security/cve/CVE-2024-53858
suse.com/security/cve/CVE-2024-53862
suse.com/security/cve/CVE-2024-54131
suse.com/security/cve/CVE-2024-54132
suse.com/security/cve/CVE-2024-6156
suse.com/security/cve/CVE-2024-6219
suse.com/security/cve/CVE-2024-6538
suse.com/security/cve/CVE-2024-8676
Left out here: 26 versions and the rest of 2 source descriptions. The JSON record has them.