CVE-2026-97335
Executive Summary
CVE-2026-97335 is an incorrect authorization vulnerability in Canonical LXD's custom storage volume creation endpoint, affecting versions 5.0.0 and later. An authenticated client with permission to create custom volumes in one project can craft a request that reads any custom storage volume (including snapshots and configuration) from any other project on the same server. The CVSS v3.1 base score is 7.7 (High), reflecting a network-reachable, low-privilege, scope-changing confidentiality breach with no integrity or availability impact.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
The flaw resides in the authorization logic governing the custom storage volume creation API endpoint. LXD uses a project-scoped permission model in which a client is granted rights to create custom volumes within a specific project. The vulnerability is a CWE-863 (Incorrect Authorization) issue: the endpoint fails to properly validate project boundaries when resolving the source volume referenced by a creation request.
According to the NVD description, the attack is triggered by a "crafted request that sets a source volume and source.project but omits source.type." The omission of source.type causes the authorization check to be bypassed, allowing the server to resolve and copy a volume belonging to a different project than the one the client is authorized for. Because the copy operation returns the volume contents — including snapshots and configuration — the client gains read access to arbitrary custom storage volumes across the entire LXD server.
Two authorization weaknesses compound the issue:
- Project boundary enforcement failure: The endpoint authorizes "create volume in project X" but does not re-verify that the referenced
source.projectmatches project X or is otherwise accessible to the caller. - Type-based validation gap: By omitting
source.type, the client sidesteps whatever type-specific branch normally enforces project scoping, causing the backend to fall through to a default resolution path that honors the attacker-suppliedsource.projectdirectly.
The vulnerability is network-reachable (AV:N), requires low privileges (PR:L — an authenticated, project-scoped client), needs no user interaction (UI:N), and changes scope (S:C) because the attacker crosses a project security boundary that should have been enforced by the same authority. Confidentiality impact is High (C:H) as arbitrary volume data can be read; there is no integrity or availability impact (I:N/A:N).
No public proof-of-concept, Nuclei template, or exploit code is currently available, and the vulnerability is not listed in CISA KEV.
Exploitation Scenarios
No public PoC is available; the attack chain below is inferred from the vulnerability class and the mechanism stated in the NVD description.
Reconnaissance / target identification: The attacker identifies a reachable LXD server (typically exposed on TCP 8443 or via a Unix socket with proxied access). They must obtain a valid client certificate or credentials for an account that has, at minimum, permission to create custom volumes in one project. LXD uses mutual TLS (mTLS) for API clients, so the attacker needs a trusted client certificate associated with a low-privileged project role.
Triggering the authorization flaw: Because the permission model grants "create custom volume in project A," the attacker targets the custom storage volume creation endpoint. They craft a request body that includes a
sourceobject with asource.projectvalue set to a victim project (e.g.,defaultor another tenant's project) and points to a target volume name, while deliberately omitting thesource.typefield. The omission is the core bypass: without it, the authorization check that should confirm the caller's permission to the source project is skipped or evaluated incorrectly.Payload/execution at the vulnerability-class level: The request instructs LXD to copy a custom volume from the attacker-specified source project into the attacker's own project. Since the endpoint returns the result of the copy (or makes the copied volume readable to the requester), the attacker obtains the data of the source volume. This is a broken access control / incorrect authorization attack — no memory corruption, injection, or code execution is involved. The "payload" is simply the malformed API request with the missing
source.typefield.Post-exploitation impact: The attacker reads the contents, snapshots, and configuration of any custom storage volume on the server, regardless of owning project. Custom volumes can contain application data, database files, configuration material, secrets, or backup snapshots. Depending on what is stored, this can lead to credential theft, lateral movement, or exfiltration of sensitive tenant data. Because scope is changed, the attacker effectively crosses all project isolation boundaries on a shared LXD server.
Impact Assessment
This is a multi-tenant isolation failure. LXD is commonly used as a virtualization/container platform by hosting providers, cloud operators, and enterprises running per-project workloads. A successful exploit allows any user with a minimal project role to read storage volumes from every project on the server — a serious cross-tenant data breach.
CVSS subscores:
- AV:N — exploitable over the network via the LXD API.
- AC:L — no special conditions; a crafted request suffices.
- PR:L — requires a valid authenticated account with volume-creation permission in some project.
- UI:N — no victim interaction required.
- S:C — the attacker's actions cross a project authorization boundary.
- C:H — arbitrary volume contents, snapshots, and config are readable.
- I:N / A:N — no direct integrity or availability impact.
Business impact includes exposure of tenant data, potential regulatory/notification obligations, and erosion of trust in multi-tenant isolation. Blast radius is the entire LXD server and every project hosted on it if the attacker holds any qualifying project role.
Detection Guidance
Sigma Rule
title: LXD Cross-Project Custom Volume Read via Missing source.type
id: 6f1c2a74-9b3e-4d21-8c55-1a7f9e0d4b62
status: experimental
description: Detects crafted LXD API requests that reference a foreign project source volume while omitting the source.type field, indicative of CVE-2026-97335.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-97335
author: valtersit.com
date: 2026/01/01
tags:
- attack.t1213
- cve.2026-97335
logsource:
category: webserver
product: lxd
detection:
selection_endpoint:
cs-uri-stem|contains:
- '/1.0/storage-pools/'
- '/1.0/projects/'
selection_method:
cs-method: 'POST'
selection_body:
cs-uri-query|contains: 'source.project'
filter_type_present:
cs-uri-query|contains: 'source.type'
condition: selection_endpoint and selection_method and selection_body and not filter_type_present
falsepositives:
- Legitimate administrative scripts that construct volume copy requests without explicit type (validate against expected client behavior)
level: high
YARA Rule
rule CVE_2026_97335_LXD_Cross_Project_Volume_Request
{
meta:
description = "Detects LXD API request payloads abusing CVE-2026-97335 by referencing a source.project without source.type"
author = "valtersit.com"
date = "2026-01-01"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-97335"
cve = "CVE-2026-97335"
strings:
$ep1 = "/1.0/storage-pools/" ascii nocase
$ep2 = "/1.0/projects/" ascii nocase
$srcproj = "\"source\"" ascii
$proj = "\"project\"" ascii
$vol = "\"volume\"" ascii
$type = "\"type\"" ascii
condition:
(($ep1 or $ep2) and $srcproj and $proj and $vol) and not $type
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-97335 LXD Cross-Project Custom Volume Read Attempt"; flow:established,to_server; http.method; content:"POST"; http.uri; content:"/1.0/storage-pools/"; http.request_body; content:"source"; content:"project"; content:!"type"; reference:cve,CVE-2026-97335; classtype:attempted-recon; sid:202697335; rev:1;)
Elastic Detection
sequence by process.entity_id
[process where event.action == "start" and process.name in ("lxc", "lxd", "curl")]
[network where network.protocol == "http" and http.request.method == "POST" and
http.request.body.text contains "source" and
http.request.body.text contains "project" and
not http.request.body.text contains "type"]
Splunk SPL Query
index=proxy OR index=web
| where (uri_path="/1.0/storage-pools/" OR uri_path="/1.0/projects/") AND http_method="POST"
| eval body=coalesce(request_body, http_request_body, "")
| where match(body, "(?i)\"source\"") AND match(body, "(?i)\"project\"") AND NOT match(body, "(?i)\"type\"")
| stats count min(_time) as first_seen max(_time) as last_seen by src_ip, uri_path, dest_host
| convert ctime(first_seen) ctime(last_seen)
Wazuh OSSEC Rule
<group name="lxd,cve-2026-97335,">
<rule id="2026973" level="12">
<decoded_as>json</decoded_as>
<field name="http.method">POST</field>
<regex type="pcre2">/1\.0/(storage-pools|projects)/</regex>
<field name="http.request.body" negate="yes">"type"</field>
<field name="http.request.body">"source"</field>
<field name="http.request.body">"project"</field>
<description>CVE-2026-97335: LXD cross-project custom volume read attempt (missing source.type)</description>
<mitre>
<id>T1213</id>
</mitre>
<group>access_control,cve_2026_97335,</group>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source).
Immediate mitigations
- Restrict network access to the LXD API endpoint (TCP 8443) to trusted management networks only; avoid exposing it to untrusted clients.
- Audit all LXD client certificates and project role assignments; revoke or downgrade any accounts holding custom-volume creation permissions that are not strictly required.
- Where feasible, disable or tightly scope custom storage volume creation permissions (
storage-volumescreate) for untrusted tenants until patched. - Monitor for the detection signals above (requests to volume/project endpoints lacking
source.type).
Patch/upgrade steps
- Upgrade LXD to a fixed release: 5.0.10, 5.21.8, or 6.10 — the versions named in the advisory. These releases correct the authorization check in the custom storage volume creation endpoint.
- Verify the running version after upgrade and restart the LXD daemon.
- Re-validate that cross-project volume references now fail authorization after the upgrade.
Long-term hardening
- Enforce strict per-project authorization checks on every API path that accepts a caller-supplied project reference, including default-path handling when optional fields (such as
source.type) are omitted. - Adopt schema validation that rejects or normalizes requests omitting required discriminator fields.
- Apply least-privilege project roles and mTLS certificate scoping; log and alert on cross-project resource access.
- Periodically review LXD security advisories for follow-up fixes.
- Enforce strict per-project authorization checks on every API path that accepts a caller-supplied project reference, including default-path handling when optional fields (such as
References
- NVD — CVE-2026-97335: https://nvd.nist.gov/vuln/detail/CVE-2026-97335
- MITRE CWE-863 (Incorrect Authorization): https://cwe.mitre.org/data/definitions/863.html
- Canonical LXD project (vendor): https://canonical.com/lxd
- LXD security announcements / release notes: https://github.com/canonical/lxd/releases
- CISA Known Exploited Vulnerabilities catalog (not listed as of this report): https://www.cisa.gov/known-exploited-vulnerabilities-catalog
No public PoC, exploit code, or in-the-wild campaign activity is currently known for CVE-2026-97335.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.