GHSA-xh8f-g2qw-gcm7 — minio
MEDIUMGHSA-xh8f-g2qw-gcm7 is a medium-severity (CVSS 4.9) Path Traversal vulnerability in github.com/minio/minio. A fix is available for github.com/minio/minio — see the affected versions and patch details below.
MinIO vulnerable to Path Traversal via msgpack Body in `ReadMultiple` Storage-REST Endpoint
Exploitation Status
No confirmed exploitation observed yet
- CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.
Exploitation and automatability from CISA’s SSVC triage for GHSA-xh8f-g2qw-gcm7.
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
How urgent is this, really
GHSA-xh8f-g2qw-gcm7 plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.
Where this sits among everything scored
Of 378,567 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.
Real-World Exposure
github.com/minio/minioReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.
Description
Impact
What kind of vulnerability is it? Who is impacted?
A path traversal vulnerability in MinIO's ReadMultiple internode storage-REST
endpoint allows a caller holding the cluster root JWT to read files from
outside the configured drive roots, bounded only by the MinIO process UID.
Distributed-erasure (multi-node) MinIO deployments are impacted. Single-node
standalone deployments do not register the route and are not affected. The
attack requires an HS512 JWT signed with MINIO_ROOT_PASSWORD and carrying
accessKey = MINIO_ROOT_USER — the same secret every peer in the cluster
holds to authenticate internode traffic, so a compromised peer or any actor in
possession of the root credential can mint one.
The ReadMultiple handler (cmd/storage-rest-server.go) decodes a msgpack
ReadMultipleReq body containing Bucket, Prefix, and Files fields and
forwards them to xlStorage.ReadMultiple (cmd/xl-storage.go) without
validation:
volumeDir := pathJoin(s.drivePath, req.Bucket) // traversal resolves here
for _, f := range req.Files {
fullPath := pathJoin(volumeDir, req.Prefix, f)
data, mt, err = s.readAllDataWithDMTime(ctx, req.Bucket, volumeDir, fullPath)
}
pathJoin calls path.Clean, which resolves .. components and produces an
absolute path anywhere on the filesystem — it is not a root jail. The global
setRequestValidityMiddleware rejects .. in r.URL.Path and r.Form but
does not inspect request bodies, so msgpack-encoded traversal bypasses it.
Sibling storage methods (StatInfoFile, ReadFileHandler, ReadVersion)
validate their volume argument through s.getVolDir(volume), which rejects
..; ReadMultiple skips this call.
The attacker sends POST /minio/storage/{drivePath}/v63/rmpl with a
msgpack-encoded body carrying ../ sequences in the Bucket field. The
server opens the resulting path via os.OpenFile with O_RDONLY|O_NOATIME
and returns its contents in the msgpack response stream.
Impact by deployment:
-
Bare-metal with
User=minioin the systemd unit — theO_NOATIMEownership check bounds the read to files owned by the MinIO UID. Reachable secrets include TLS private keys, KMS/KES key material, systemd credentials, and data belonging to other tenants sharing the same UID on the host. Secrets leaked this way persist across cluster credential rotation. -
Containerized running as UID 0 (the historical default for the official Docker image,
docker-composeexamples, and Helm charts withoutsecurityContext.runAsNonRoot) — the primitive escalates to arbitrary host-filesystem disclosure:/etc/shadow,/root/**, Kubernetes service-account tokens, cloud-init metadata caches.
Affected components: cmd/storage-rest-server.go (ReadMultiple handler),
cmd/xl-storage.go (xlStorage.ReadMultiple).
CWE: CWE-22 (Improper Limitation of a Pathname to a Restricted Directory — 'Path Traversal')
CVSS v4.0 Score: 6.9 (Medium)
Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N
Affected Versions
All MinIO releases from RELEASE.2022-07-24T01-54-52Z through the final
release of the minio/minio open-source project, RELEASE.2025-09-07T16-13-09Z.
The vulnerability was introduced in commit
f939d1c18
("Independent Multipart Uploads",
PR #15346), which added the
ReadMultiple storage-REST endpoint as part of the multipart upload
redesign. The first affected release is RELEASE.2022-07-24T01-54-52Z.
Patches
Fixed in: MinIO AIStor RELEASE.2026-04-14T21-32-45Z (recommended
upgrade target). The fix — which removed the ReadMultiple handler, the
corresponding storage-driver method, the msgpack datatypes, the REST-client
wrapper, and the route registration — first shipped in MinIO AIStor
RELEASE.2024-10-23T19-38-07Z. Every AIStor release from
RELEASE.2024-10-23T19-38-07Z onward is unaffected; users should upgrade to
RELEASE.2026-04-14T21-32-45Z or later to pick up the accumulated fixes and
improvements shipped since.
Binary Downloads
| Platform | Architecture | Download |
|---|---|---|
| Linux | amd64 | minio |
| Linux | arm64 | minio |
| macOS | arm64 | minio |
| macOS | amd64 | minio |
| Windows | amd64 | minio.exe |
FIPS Binaries
| Platform | Architecture | Download |
|---|---|---|
| Linux | amd64 | minio.fips |
| Linux | arm64 | minio.fips |
Package Downloads
| Format | Architecture | Download |
|---|---|---|
| DEB | amd64 | minio_20260414213245.0.0_amd64.deb |
| DEB | arm64 | minio_20260414213245.0.0_arm64.deb |
| RPM | amd64 | minio-20260414213245.0.0-1.x86_64.rpm |
| RPM | arm64 | minio-20260414213245.0.0-1.aarch64.rpm |
Container Images
# Standard
docker pull quay.io/minio/aistor/minio:RELEASE.2026-04-14T21-32-45Z
podman pull quay.io/minio/aistor/minio:RELEASE.2026-04-14T21-32-45Z
# FIPS
docker pull quay.io/minio/aistor/minio:RELEASE.2026-04-14T21-32-45Z.fips
podman pull quay.io/minio/aistor/minio:RELEASE.2026-04-14T21-32-45Z.fips
Homebrew (macOS)
brew install minio/aistor/minio
Workarounds
If upgrading is not immediately possible:
-
Rotate the root credential and restrict who holds it. The exploit requires a JWT signed with
MINIO_ROOT_PASSWORD. Treat the root credential as the host-filesystem disclosure primitive that it is: rotate it after any suspected exposure, store it only in the secret manager that bootstraps the cluster, and do not hand it to applications or operators who only need object-level access. -
Do not run the MinIO container as UID 0. Set
securityContext.runAsNonRoot: true(and a non-zerorunAsUser) in Kubernetes manifests, or add--usertodocker run. This reduces the blast radius from arbitrary host-filesystem disclosure to MinIO-UID-owned files only. -
Restrict the internode storage-REST port at the network layer. In distributed deployments, the storage-REST route is served on the same port as the S3 API by default. Where feasible, use
--internode-portto expose internode traffic on a separate interface reachable only from other cluster peers, and block that interface from client networks.
Credits
- Finders: Discovered by Claude, Anthropic's AI assistant, and triaged by Adrian Denkiewicz at Doyensec in collaboration with Anthropic Research.
Resources
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐹Go | github.com/minio/minio | ≥ 0.0.0-20220724015452&&< 0.0.0-20260414213245 | 0.0.0-20260414213245go get github.com/minio/minio@v0.0.0-20260414213245 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for github.com/minio/minio, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update github.com/minio/minio to 0.0.0-20260414213245 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-xh8f-g2qw-gcm7 is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like GHSA-xh8f-g2qw-gcm7 can be triaged on real exposure rather than presence alone.
Tailored to GHSA-xh8f-g2qw-gcm7. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is GHSA-xh8f-g2qw-gcm7 in your dependencies?
O3 Security finds GHSA-xh8f-g2qw-gcm7 across Go dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.