Summary
User provided image and backup tarballs would be unpacked and YAML files parsed without any size restrictions. This was making it easy for an authenticated user to provide a crafted image or backup tarball that when parsed by Incus would lead to a very large YAML document being loaded into memory, potentially causing the entire server to run out of memory.
Details
It was found that getImageMetadata and backup.GetInfo call yaml.NewDecoder(tr).Decode() directly on the tar reader without limiting how many bytes the YAML decoder can consume. The tar entry hdr.Size is not checked before decoding.
A tar archive can be crafted in which metadata.yaml or backup/index.yaml declares a large size in the tar header, causing the YAML decoder to read and allocate proportional memory on the server. The gopkg.in/yaml.v2 library mitigates YAML alias and anchor bombs, such as “billion laughs,” through its built-in excessive-aliasing check. However, large flat YAML documents with many keys or long string values can still produce linear but amplified memory consumption of approximately 5x to 6x the input size.
A 200 MB tar entry for metadata.yaml may cause approximately 1.2 GB of heap allocations during decode, which may be sufficient to trigger an out-of-memory condition on a constrained daemon or significantly degrade service. Because the decode occurs in the daemon process, excessive garbage-collection pressure can affect concurrent operations. Appropriate API permissions are required to upload an image or backup archive.
Mitigating factors include the fact that the amplification is linear rather than exponential, at approximately 5x to 6x, and that upload bandwidth is the practical bottleneck for delivering large payloads.
Affected Files:
- https://github.com/lxc/incus/blob/v6.22.0/cmd/incusd/images.go#L1456
- https://github.com/lxc/incus/blob/v6.22.0/internal/server/backup/backup_info.go#L87
- https://github.com/lxc/incus/blob/v6.22.0/internal/server/backup/backup_info.go#L115
Image metadata parsing reads YAML directly from the tar stream:
Affected Code:
if hdr.Name == "metadata.yaml" || hdr.Name == "./metadata.yaml" {
err = yaml.NewDecoder(tr).Decode(&result)
Backup info parsing does the same:
Affected Code:
if hdr.Name == backupIndexPath {
err = yaml.NewDecoder(tr).Decode(&result)
if result.Config == nil && hdr.Name == "backup/container/backup.yaml" {
err = yaml.NewDecoder(tr).Decode(&result.Config)
This was confirmed as follows:
Command:
go test ./test/fuzz -run='TestUnboundedYAMLMetadataDecode' -count=1 -v
Output:
=== RUN TestUnboundedYAMLMetadataDecode
image_metadata_poc_test.go:80: metadata.yaml size: 10.2 MB
image_metadata_poc_test.go:113: metadata.yaml hdr.Size = 10688940 bytes (10.2 MB) -- no size
check exists in getImageMetadata before yaml.NewDecoder(tr).Decode()
image_metadata_poc_test.go:124: decoded 50000 properties from 10.2 MB metadata.yaml
image_metadata_poc_test.go:125: yaml.NewDecoder(tr).Decode() accepted 10.2 MB metadata.yaml
with 50000 properties -- no hdr.Size check or io.LimitReader in images.go:1457 or
backup_info.go:88
--- FAIL: TestUnboundedYAMLMetadataDecode (0.11s)
FAIL
It is recommended to add a size check on hdr.Size before YAML decoding and to wrap the tar reader in io.LimitReader.
Proposed Fix:
const maxMetadataSize = 1 << 20 // 1 MB
if hdr.Size > maxMetadataSize {
return nil, fmt.Errorf("metadata entry too large: %d bytes", hdr.Size)
}
err = yaml.NewDecoder(io.LimitReader(tr, maxMetadataSize)).Decode(&result)
A patch is available at https://github.com/lxc/incus/releases/tag/v7.0.0.
Credit
This issue was discovered and reported by the team at 7asecurity (https://7asecurity.com/)
Impact
The application allocates resources such as memory, threads, or file descriptors based on untrusted input without enforcing a cap. Typical impact: resource exhaustion leading to denial of service.
CVE-2026-41648 has a CVSS score of 5.0 (Medium). The vector is network-reachable, low privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. No fixed version is listed yet, so configuration controls and monitoring matter more in the interim.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Remediation advice
In the interim: Apply per-request resource limits and enforce them before allocation. Rate-limit callers at the network or application layer.
Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.
Frequently Asked Questions
- What is CVE-2026-41648? CVE-2026-41648 is a medium-severity allocation of resources without limits or throttling vulnerability in github.com/lxc/incus/v6/cmd/incusd (go), affecting versions <= 6.23.0. No fixed version is listed yet. The application allocates resources such as memory, threads, or file descriptors based on untrusted input without enforcing a cap.
- How severe is CVE-2026-41648? CVE-2026-41648 has a CVSS score of 5.0 (Medium). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
- Which versions of github.com/lxc/incus/v6/cmd/incusd are affected by CVE-2026-41648? github.com/lxc/incus/v6/cmd/incusd (go) versions <= 6.23.0 is affected.
- Is there a fix for CVE-2026-41648? No fixed version is listed for CVE-2026-41648 yet. Monitor the advisory for updates and apply mitigations in the interim.
- Is CVE-2026-41648 exploitable, and should I be worried? Whether CVE-2026-41648 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether CVE-2026-41648 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix CVE-2026-41648? No fixed version is listed yet. In the interim: Apply per-request resource limits and enforce them before allocation. Rate-limit callers at the network or application layer.