CVE-2026-81496
Published:October 12, 2026
Updated:October 13, 2026
Summary "POST /1.0/instances" with an "application/octet-stream" body (instance backup import) reads the instance name from the tarball's "backup/index.yaml" verbatim and uses it as an on-disk path segment. A project user with the "can_create_instances" entitlement can set "name: ../../../../etc/cron.d/x", causing the root Incus daemon to create a directory and unpack attacker-controlled tarball content outside the storage pool - before any name validation runs. This yields arbitrary directory creation and arbitrary-content file write as root, and thus host RCE. ## Root Cause In "createFromBackup" ("cmd/incusd/instances_post.go"), the tarball metadata is parsed by "backup.GetInfo" ("internal/server/backup/backup_info.go:64-160"), which loads "result.Name" straight from "index.yaml" via YAML unmarshal with NO validation - no "filepath.Clean", no "IsAPIName", no "/" or ".." rejection. The name then flows to "pool.CreateInstanceFromBackup" -> "project.Instance(srcBackup.Project, srcBackup.Name)" ("internal/server/storage/backend.go:744") -> "vol.MountPath()" -> "GetVolumeMountPath" = "VarPath("storage-pools", pool, "containers", <name>)" -> "EnsureMountPath" "os.Mkdir" + "CreateVolumeFromBackup" content unpack. "instance.ValidName" exists only at "instances_post.go:1452", which is on the JSON-dispatch path and is never reached for the octet-stream branch (dispatch returns at ":1157"). ## Impact Root-owned arbitrary directory creation and arbitrary-content file write outside the storage pool (e.g. "/etc/cron.d/"), leading to host remote code execution. Snapshot names ("bInfo.Snapshots[]") are a second identical vector. ## Proof of Concept 1. Build an instance backup tarball whose "backup/index.yaml" sets "name: ../../../../etc/cron.d/pwn" and whose "container/rootfs" contains a crafted cron file body. 2. "curl -X POST --data-binary @backup.tar -H 'Content-Type: application/octet-stream' https://incus/1.0/instances" (as a user with "can_create_instances"). 3. The daemon writes attacker content to "/etc/cron.d/pwn" as root. ## Attack Chain 1. Entry: "POST /1.0/instances", "Content-Type: application/octet-stream", no "X-Incus-name". Guard: none for this branch -> "createFromBackup" ("instances_post.go:1157"). 2. Parse: "bInfo, _ := backup.GetInfo(backupFile, ...)" ("instances_post.go:851") reads "Name" from "index.yaml". Guard: "GetInfo" ("backup_info.go:64-160") - none. Bypass proof: field returned untouched from YAML unmarshal; no "Clean"/"IsAPIName"/".." check in the function (verified at HEAD). 3. Restriction check: "AllowInstanceCreation" ("instances_post.go:871") validates project restrictions only, not name syntax. Passes. 4. Sink: "pool.CreateInstanceFromBackup(*bInfo, ...)" ("instances_post.go:992") -> "project.Instance(proj, bInfo.Name)" ("backend.go:744") -> "vol.MountPath()" -> "EnsureMountPath" "os.Mkdir" ("internal/server/storage/drivers/volume.go") + content unpack, as root, BEFORE "internalImportFromBackup" and BEFORE the unreachable "ValidName" at ":1452". 5. Impact: root arbitrary dir create + attacker-content file write -> host RCE. ## Bypass Evidence No guard exists between the tarball name and the disk write. Go's "filepath.Join" collapses "..": "filepath.Join("/var/lib/incus/storage-pools/p/containers","../../../../etc/cron.d/x")" = "/var/lib/etc/cron.d/x" (verified by running it; deeper ".." reaches "/etc/cron.d/x"). Same class as CVE-2026-48753 but a distinct, unfixed entry point (record name used as path segment, not a symlink inside the archive payload). ## Affected Versions "<= 7.2.0" (vulnerable code verified present on latest release tag v7.2.0 and on HEAD 60d85b3e; no fix commit on "cmd/incusd/instances_post.go" between v7.2.0 and HEAD). ## Suggested Fix Apply "instance.ValidName(bInfo.Name, false)" (and validate each snapshot name) immediately after "backup.GetInfo", before any storage I/O. ## Credit Vulnerability independently discovered and responsibly disclosed by Zhixi "Jace" Sun (@manus-use).
Affected Packages
https://github.com/lxc/incus.git (GITHUB):
Affected version(s) >=v0.1.0 <v7.3.0Fix Suggestion:
Update to version v7.3.0github.com/lxc/incus/v7 (GO):
Affected version(s) >=v7.1.0 <v7.3.0Fix Suggestion:
Update to version v7.3.0github.com/lxc/incus (GO):
Affected version(s) >=v0.1.0 <v7.3.0Fix Suggestion:
Update to version v7.3.0Related Resources (3)
Do you need more information?
Contact UsCVSS v4
Base Score:
9.4
Attack Vector
NETWORK
Attack Complexity
LOW
Attack Requirements
NONE
Privileges Required
LOW
User Interaction
NONE
Vulnerable System Confidentiality
HIGH
Vulnerable System Integrity
HIGH
Vulnerable System Availability
HIGH
Subsequent System Confidentiality
HIGH
Subsequent System Integrity
HIGH
Subsequent System Availability
HIGH
CVSS v3
Base Score:
9.9
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
LOW
User Interaction
NONE
Scope
CHANGED
Confidentiality
HIGH
Integrity
HIGH
Availability
HIGH