Miggo Logo

CVE-2025-54293: Canonical LXD Path Traversal Vulnerability in Instance Log File Retrieval Function

6.5

CVSS Score
3.1

Basic Information

EPSS Score
0.45561%
Published
10/2/2025
Updated
10/2/2025
KEV Status
No
Technology
TechnologyGo

Technical Details

CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Package NameEcosystemVulnerable VersionsFirst Patched Version
github.com/canonical/lxdgo>= 4.0, < 5.21.45.21.4
github.com/canonical/lxdgo>= 6.0, < 6.56.5
github.com/canonical/lxdgo>= 0.0.0-20200331193331-03aab09f5b5c, < 0.0.0-20250224180022-ec09b24179f30.0.0-20250224180022-ec09b24179f3

Vulnerability Intelligence
Miggo AIMiggo AI

Miggo AIRoot Cause Analysis

The vulnerability is a classic path traversal issue within the LXD instance log file retrieval functionality. The root cause lies in the validLogFileName and validExecOutputFileName functions in lxd/instance_logs.go. These functions performed inadequate validation on filenames, failing to properly sanitize user-provided input that could contain directory traversal sequences (e.g., ..).

The analysis of the provided pull request, specifically commit c427c4413c28e0070d06bcc8ae49df2e34b9cd33, confirms this. The patch replaces a weak blocklist check (strings.Contains(fname, "..")) with a more robust validation function, shared.IsFileName(). The original check was flawed because the application used filepath.Join which would normalize the path before the validation was performed, effectively neutralizing the check.

The primary vulnerable functions are validLogFileName and validExecOutputFileName due to their insufficient input validation. The functions instanceLogGet and instanceLogDelete are the exposed API endpoints that consume these vulnerable validation functions, making them the entry points for exploitation. During an exploit, a runtime profile would show a call chain starting with instanceLogGet which then calls validLogFileName with the malicious path.

Vulnerable functions

validLogFileName
lxd/instance_logs.go
The function `validLogFileName` in the vulnerable version uses `strings.Contains` to check for path traversal characters. This check is insufficient because it can be bypassed. The vulnerability description explains that Go's `filepath.Join` normalizes the path *before* this validation occurs, rendering the check ineffective against payloads like `snapshot_../../../../../../../../../../etc/passwd`. The fix replaces this weak check with a call to `shared.IsFileName`, which provides a more robust validation against path traversal.
validExecOutputFileName
lxd/instance_logs.go
Similar to `validLogFileName`, the `validExecOutputFileName` function uses an inadequate `strings.Contains` check to prevent path traversal. This allows an attacker to craft a malicious filename that, when combined with the creation of a symbolic link inside a container, can grant access to arbitrary files on the host system. The fix replaces the flawed check with `shared.IsFileName`.
instanceLogGet
lxd/instance_logs.go
This function is the HTTP handler for retrieving instance log files. It takes a filename from the URL path, which is user-controlled, and passes it to the vulnerable `validLogFileName` function for validation. Because the validation was flawed, this function becomes the entry point for the path traversal attack, ultimately leading to arbitrary file read.
instanceLogDelete
lxd/instance_logs.go
This function handles the deletion of log files. It also uses the vulnerable `validLogFileName` function to validate the filename provided by the user. While the primary exploit focuses on reading files via `instanceLogGet`, this function is also affected by the same path traversal vulnerability, potentially allowing an attacker to delete arbitrary files if the permissions allow.

WAF Protection Rules

WAF Rule

### Imp**t *lt*ou** outsi** t** s*op* o* t*is p*n*tr*tion t*st, * p*t* tr*v*rs*l vuln*r**ility *xists in t** v*li*Lo**il*N*m* *un*tion t**t v*li**t*s lo* *il* n*m*s in lx*/inst*n**_lo*s.*o in t** LX* *.* LTS s*ri*s. T*is vuln*r**ility w*s *ix** in P

Reasoning

T** vuln*r**ility is * *l*ssi* p*t* tr*v*rs*l issu* wit*in t** LX* inst*n** lo* *il* r*tri*v*l *un*tion*lity. T** root **us* li*s in t** `v*li*Lo**il*N*m*` *n* `v*li**x**Output*il*N*m*` *un*tions in `lx*/inst*n**_lo*s.*o`. T**s* *un*tions p*r*orm** i