# REPRO-2026-00220: JuiceFS through 1.3.1 exposes debug/metrics endpoints via shared http.DefaultServeMux, enabling authentication bypass and leakage of sensitive metadata connection strings, with potential DoS via profiling handlers. ## Summary Status: published Severity: high Type: security Confidence: high ## Identifiers REPRO ID: REPRO-2026-00220 CVE: CVE-2026-59092 ## Package Name: JuiceFS (juicedata/juicefs) Ecosystem: go Affected: JuiceFS <= 1.3.1 Fixed: commit a46979cdd4082217081ee99b931ddc53d038e47a ## Root Cause # Root Cause Analysis: CVE-2026-59092 ## Summary JuiceFS through 1.3.1 exposes debug and metrics HTTP endpoints via the shared `http.DefaultServeMux`, enabling unauthenticated remote attackers to access sensitive `/debug/pprof/*` handlers. The `/debug/pprof/cmdline` endpoint leaks the full process command line, which includes metadata engine connection strings containing database credentials (e.g., Redis passwords), granting full read/write access to filesystem metadata. Other pprof handlers (`/debug/pprof/heap`, `/debug/pprof/goroutine`, `/debug/pprof/profile`) leak internal runtime state and can be abused for denial-of-service via CPU profiling. ## Impact - **Package/component affected**: `cmd/mount.go` (`exposeMetrics` function), `pkg/fs/http.go` (`StartHTTPServer` for WebDAV), `pkg/sync/cluster.go` (`startManager`) - **Affected versions**: JuiceFS through 1.3.1 (fixed in commit `a46979cdd4082217081ee99b931ddc53d038e47a`) - **Risk level**: High (CVSS 7.7) — unauthenticated credential disclosure leading to metadata engine compromise and potential DoS ## Impact Parity - **Disclosed/claimed maximum impact**: Authentication bypass; disclosure of metadata engine connection strings with DB credentials via `/debug/pprof/cmdline`; access to internal state via other pprof handlers; potential DoS via profiling endpoints - **Reproduced impact from this run**: - Unauthenticated access to `/debug/pprof/cmdline` returns HTTP 200 with full command line including Redis password `s3cr3tPass` from the metadata URL `redis://:s3cr3tPass@127.0.0.1:6379/1` - All pprof endpoints (`/debug/pprof/`, `/debug/pprof/heap`, `/debug/pprof/goroutine`, `/debug/pprof/profile`) return HTTP 200 without authentication - Fixed version returns HTTP 404 for all pprof endpoints while `/metrics` still works - **Parity**: `full` — the authentication bypass and credential leakage are fully demonstrated through the real product (JuiceFS gateway) via the remote HTTP API surface - **Not demonstrated**: Full metadata compromise (using the leaked credentials to access the Redis metadata engine) and DoS via profiling — these are downstream consequences of the credential leak, not separate reproduction targets ## Root Cause The `exposeMetrics()` function in `cmd/mount.go` calls `http.Handle("/metrics", ...)` which registers the metrics handler on the shared `http.DefaultServeMux`. It then starts the HTTP server with `http.Serve(ln, nil)`, where the `nil` handler defaults to `http.DefaultServeMux`. Since the `net/http/pprof` package is imported via `_ "net/http/pprof"` in multiple files (`cmd/main.go`, `cmd/mount.go`, `cmd/gateway.go`, `cmd/format.go`, `cmd/sync.go`), its `init()` function registers pprof handlers (`/debug/pprof/cmdline`, `/debug/pprof/heap`, `/debug/pprof/goroutine`, `/debug/pprof/profile`, etc.) on `http.DefaultServeMux` at program startup. As a result, all pprof endpoints are served without authentication alongside the metrics endpoint on whatever address the metrics server binds to (default `127.0.0.1:9567`, but configurable to `0.0.0.0:9567` for remote access). The same pattern affects: - `pkg/fs/http.go` `StartHTTPServer()` — WebDAV server uses `http.ListenAndServe(addr, nil)` - `pkg/sync/cluster.go` `startManager()` — sync manager uses `http.Serve(l, nil)` **Fix commit**: `a46979cdd4082217081ee99b931ddc53d038e47a` ("cmd: use a dedicated ServeMux to avoid exposing pprof/metrics") The fix creates a dedicated `http.NewServeMux()` for each HTTP server and passes it to `http.Serve(ln, mux)` instead of `nil`, isolating the application handlers from the pprof handlers registered on `DefaultServeMux`. ### Vulnerable code (`cmd/mount.go`, commit `f60a90fc`): ```go http.Handle("/metrics", promhttp.HandlerFor(...)) // registers on DefaultServeMux // ... http.Serve(ln, nil) // nil → uses DefaultServeMux → exposes pprof ``` ### Fixed code (`cmd/mount.go`, commit `a46979cd`): ```go mux := http.NewServeMux() // dedicated mux mux.Handle("/metrics", promhttp.HandlerFor(...)) // registers on dedicated mux // ... http.Serve(ln, mux) // uses dedicated mux → no pprof exposure ``` ## Reproduction Steps 1. **Reference**: `bundle/repro/reproduction_steps.sh` 2. **What the script does**: - Installs Go 1.25.0 and Redis if not already available - Clones the JuiceFS repository (or reuses the project cache) - Builds the vulnerable binary at commit `f60a90fc` (parent of the fix) - Builds the fixed binary at commit `a46979cd` - Starts Redis with password `s3cr3tPass` to simulate a credential-bearing metadata engine - Formats a JuiceFS volume using `redis://:s3cr3tPass@127.0.0.1:6379/1` as the metadata URL - Starts the JuiceFS S3 gateway with `--metrics 0.0.0.0:9567` (remotely accessible metrics port) - Sends unauthenticated HTTP GET to `/debug/pprof/cmdline` on the metrics port - Verifies the response contains the Redis password (vulnerable version) - Repeats with the fixed binary and verifies HTTP 404 (no pprof exposure) 3. **Expected evidence of reproduction**: - Vulnerable version: HTTP 200 for `/debug/pprof/cmdline` with response body containing `redis://:s3cr3tPass@127.0.0.1:6379/1` - Fixed version: HTTP 404 for `/debug/pprof/cmdline` - Both versions: HTTP 200 for `/metrics` (metrics endpoint still functional after fix) ## Evidence ### Log files - `bundle/logs/gateway-vuln.log` — vulnerable gateway startup and metrics listening log - `bundle/logs/gateway-fixed.log` — fixed gateway startup and metrics listening log - `bundle/logs/redis.log` — Redis server log - `bundle/logs/format.log` — JuiceFS volume format log ### Response artifacts - `bundle/repro/artifacts/vuln-cmdline-response.txt` — raw response from vulnerable `/debug/pprof/cmdline` - `bundle/repro/artifacts/fixed-cmdline-response.txt` — raw response from fixed `/debug/pprof/cmdline` - `bundle/repro/artifacts/vuln-metrics-response.txt` — Prometheus metrics from vulnerable version ### Key excerpts **Vulnerable `/debug/pprof/cmdline` response (HTTP 200):** ``` /data/pruva/project-cache/.../juicefs-vuln gateway redis://:s3cr3tPass@127.0.0.1:6379/1 localhost:9000 --metrics 0.0.0.0:9567 --no-banner ``` **Fixed `/debug/pprof/cmdline` response (HTTP 404):** ``` 404 page not found ``` **Vulnerable pprof endpoints (all HTTP 200 without auth):** ``` /debug/pprof/: HTTP 200 /debug/pprof/heap: HTTP 200 /debug/pprof/goroutine: HTTP 200 /debug/pprof/profile: HTTP 200 /metrics: HTTP 200 ``` **Fixed pprof endpoints (all HTTP 404):** ``` /debug/pprof/: HTTP 404 /debug/pprof/heap: HTTP 404 /debug/pprof/goroutine: HTTP 404 /debug/pprof/profile: HTTP 404 /metrics: HTTP 200 ``` ### Environment details - Go version: go1.25.0 linux/amd64 - Redis version: 8.0.5 - JuiceFS vulnerable commit: `f60a90fc0ad52d2bb1f44f38a04d55044fc91d50` - JuiceFS fixed commit: `a46979cdd4082217081ee99b931ddc53d038e47a` - Architecture: x86_64 ## Recommendations / Next Steps 1. **Upgrade**: Update to a JuiceFS version containing commit `a46979cd` or later 2. **Network restriction**: Bind the metrics port to localhost (`127.0.0.1:9567`) rather than `0.0.0.0:9567` unless remote monitoring is explicitly required 3. **Debug agent**: Use the `--no-agent` flag to disable the debug agent on port 6060, which still uses `http.ListenAndServe(debugAgent, nil)` with `DefaultServeMux` even after the fix (though it binds to localhost only) 4. **Firewall**: Restrict network access to the metrics and debug ports using firewall rules 5. **Credential rotation**: If credentials were exposed via this vulnerability, rotate all metadata engine passwords immediately ## Additional Notes - **Idempotency**: The script was run twice consecutively, both times confirming the vulnerability with identical results (exit code 0) - **Scope**: The fix addresses `exposeMetrics` (mount/gateway/sync/mdtest), `StartHTTPServer` (WebDAV), and `startManager` (sync cluster). The debug agent in `cmd/main.go` line 336 (`http.ListenAndServe(debugAgent, nil)`) remains unchanged but is bound to `127.0.0.1` only, limiting it to local access - **Negative control**: The fixed version binary was built from the exact fix commit and demonstrates that pprof endpoints return 404 while `/metrics` continues to function, proving the fix is surgical and does not break metrics collection ## Reproduction Details Reproduced: 2026-07-03T15:53:57.609Z Duration: 886 seconds Tool calls: 158 Turns: Unknown Handoffs: 2 ## Quick Verification Run one of these commands to verify locally: pruva-verify REPRO-2026-00220 pruva-verify CVE-2026-59092 Or open in GitHub Codespaces (zero-friction, auto-runs): https://github.com/codespaces/new?ref=repro/REPRO-2026-00220&repo=N3mes1s/pruva-sandbox Or download and run the script manually: curl -O https://api.pruva.dev/v1/reproductions/REPRO-2026-00220/artifacts/bundle/repro/reproduction_steps.sh chmod +x reproduction_steps.sh ./reproduction_steps.sh WARNING: Run in a sandboxed environment. This exploits a real vulnerability. ## References - NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-59092 - Source: https://nvd.nist.gov/vuln/detail/CVE-2026-59092 ## Artifacts - bundle/repro/reproduction_steps.sh (reproduction_script, 15752 bytes) - bundle/repro/rca_report.md (analysis, 8382 bytes) - bundle/vuln_variant/reproduction_steps.sh (reproduction_script, 20021 bytes) - bundle/vuln_variant/rca_report.md (analysis, 11928 bytes) - bundle/ticket.md (ticket, 2513 bytes) - bundle/ticket.json (other, 3603 bytes) - bundle/AGENTS.repro.md (documentation, 192 bytes) - bundle/logs/cmdline-vuln-response.txt (other, 170 bytes) - bundle/logs/redis.log (log, 2944 bytes) - bundle/logs/format.log (log, 1135 bytes) - bundle/logs/gateway-vuln.log (log, 1686 bytes) - bundle/logs/gateway-fixed.log (log, 1686 bytes) - bundle/repro/artifacts/vuln-cmdline-response.txt (other, 170 bytes) - bundle/repro/artifacts/vuln-metrics-response.txt (other, 77115 bytes) - bundle/repro/artifacts/fixed-cmdline-response.txt (other, 19 bytes) - bundle/repro/runtime_manifest.json (other, 710 bytes) - bundle/repro/validation_verdict.json (other, 748 bytes) - bundle/logs/vuln_variant/fixed_version.txt (other, 346 bytes) - bundle/logs/vuln_variant/redis.log (log, 10301 bytes) - bundle/logs/vuln_variant/format.log (log, 785 bytes) - bundle/logs/vuln_variant/gateway-vuln.log (log, 1689 bytes) - bundle/logs/vuln_variant/vuln-debugagent-cmdline.txt (other, 170 bytes) - bundle/logs/vuln_variant/vuln-debugagent-cmdline-pretty.txt (other, 239 bytes) - bundle/logs/vuln_variant/gateway-fixed.log (log, 1689 bytes) - bundle/logs/vuln_variant/fixed-debugagent-cmdline.txt (other, 171 bytes) - bundle/logs/vuln_variant/fixed-debugagent-cmdline-pretty.txt (other, 240 bytes) - bundle/logs/vuln_variant/gateway-fixed-noagent.log (log, 1690 bytes) - bundle/logs/vuln_variant/variant-run-1.log (log, 4174 bytes) - bundle/logs/vuln_variant/variant-run-2.log (log, 4171 bytes) - bundle/logs/vuln_variant/variant-run-3.log (log, 871 bytes) - bundle/logs/vuln_variant/variant-run-4.log (log, 4171 bytes) - bundle/logs/vuln_variant/variant-run-5.log (log, 4171 bytes) - bundle/logs/vuln_variant/variant-run-6.log (log, 4171 bytes) - bundle/logs/vuln_variant/variant-run-7.log (log, 4171 bytes) - bundle/vuln_variant/variant_runtime_result.json (other, 457 bytes) - bundle/vuln_variant/patch_analysis.md (documentation, 7695 bytes) - bundle/vuln_variant/variant_manifest.json (other, 4221 bytes) - bundle/vuln_variant/validation_verdict.json (other, 2360 bytes) - bundle/vuln_variant/source_identity.json (other, 1511 bytes) - bundle/vuln_variant/runtime_manifest.json (other, 2499 bytes) - bundle/vuln_variant/root_cause_equivalence.json (other, 2349 bytes) ## API Access - JSON: https://api.pruva.dev/v1/reproductions/REPRO-2026-00220 - Script: https://api.pruva.dev/v1/reproductions/REPRO-2026-00220/artifacts/bundle/repro/reproduction_steps.sh - Web: https://pruva.dev/r/REPRO-2026-00220 ## For AI Assistants To help users with this reproduction: 1. The `pruva-verify` command is the simplest way to run the reproduction 2. The script downloads and runs automatically in an isolated temp directory 3. Always recommend running in a VM, container, or disposable environment 4. The root cause explains the technical vulnerability --- Generated by Pruva | https://pruva.dev