CVE-2025-60021: Verified Repro With Script Download
CVE-2025-60021: Apache bRPC: Remote Command Injection in Heap Profiler
CVE-2025-60021 is verified against brpc · cpp. Affected versions: 1.11.0 to <1.15.0. Fixed in 1.15.0. Vulnerability class: Command Injection. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00072.
What Is CVE-2025-60021?
CVE-2025-60021 is a high-severity remote command injection vulnerability in Apache bRPC's built-in heap profiler endpoint (/pprof/heap), reachable when jemalloc profiling is enabled. Pruva reproduced it (reproduction REPRO-2026-00072).
CVE-2025-60021 Severity & CVSS Score
CVE-2025-60021 is rated critical severity, with a CVSS base score of 9.8 out of 10.
Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.
Affected brpc Versions
brpc · cpp versions 1.11.0 to <1.15.0 are affected.
How to Reproduce CVE-2025-60021
pruva-verify REPRO-2026-00072 curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00072/artifacts/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2025-60021
Reproduced by Pruva's autonomous agents — 503 tool calls over 48 min. Full root-cause analysis and the complete transcript are below.
How the agent worked
Root Cause and Exploit Chain for CVE-2025-60021
Summary
Apache bRPC versions 1.11.0 through 1.14.x allow remote command injection via the built-in /pprof/heap endpoint when jemalloc profiling is enabled. The handler concatenates the user-controlled extra_options query parameter directly into a shell command used to invoke jeprof, and the command is executed through popen, allowing shell metacharacters to execute arbitrary commands.
Impact
- Component:
src/brpc/details/jemalloc_profiler.cpp(jemalloc heap profiler endpoint/pprof/heap) - Affected versions: 1.11.0 to <1.15.0
- Risk level: Important — remote command execution as the service user, enabling data exfiltration and lateral movement.
Root Cause
The heap profiler handler builds a command line for jeprof and appends the extra_options query parameter without validation:
- Vulnerable code (1.14.1):
cmd_str += " --" + *uri_extra_options + " "; - The command is executed via
butil::read_command_output, which usespopen()(/bin/sh -c), so shell metacharacters inextra_optionsare interpreted.
The fix in 1.15.0 introduces a whitelist of allowed extra_options values and ignores unsupported inputs, preventing shell metacharacter injection. See PR https://github.com/apache/brpc/pull/3101.
Reproduction Steps
- Run
repro/reproduction_steps.sh. - The script builds bRPC 1.14.1 and 1.15.0, starts the echo server with jemalloc profiling enabled, then issues crafted
/pprof/heaprequests. - Expected evidence:
uid=...appears inlogs/vuln_response.txtfor 1.14.1 and is absent inlogs/fixed_response.txtfor 1.15.0.
Evidence
- Vulnerable response (1.14.1):
logs/vuln_response.txtuid=0(root) gid=0(root) groups=0(root)(line 82)
- Fixed response (1.15.0):
logs/fixed_response.txt- No
uid=output present.
- No
- Build and runtime logs:
logs/echo_server_vuln.loglogs/echo_server_fixed.log
Environment details:
- Ubuntu with system dependencies installed via
apt-get. - jemalloc enabled via
MALLOC_CONF=prof:trueandLD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2.
Recommendations / Next Steps
- Upgrade to bRPC 1.15.0 or apply the whitelist patch from PR #3101.
- Consider avoiding shell execution entirely (pass arguments directly to
execvewithout shell) for any future tooling. - Add regression tests for
/pprof/heapto ensure only approved options are accepted.
Additional Notes
- Idempotency verified:
repro/reproduction_steps.shexecuted twice successfully. - The exploit only applies when jemalloc profiling is enabled and
/pprof/heapis reachable.
CVE-2025-60021 Reproduction Transcript
The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.
Full session Replay every step — scrub the timeline or play it back.
ls -la /workspacels: cannot access '/workspace': No such file or directory
{"output":"{\"returncode\": 2, \"stdout\": \"\", \"stderr\": \"ls: cannot access '/workspace': No such file or directory\\n\", \"cwd\": \"/home/user/pruva/artifacts/runs/cve-2025-60021/20260120-233404/cve-2025-60021\"}"}pwd/home/user/pruva/artifacts/runs/cve-2025-60021/20260120-233404/cve-2025-60021
{"output":"{\"returncode\": 0, \"stdout\": \"/home/user/pruva/artifacts/runs/cve-2025-60021/20260120-233404/cve-2025-60021\\n\", \"stderr\": \"\", \"cwd\": \"/home/user/pruva/artifacts/runs/cve-2025-60021/20260120-233404/cve-"}ls -la /home/user/pruva/artifacts/runs/cve-2025-60021/20260120-233404total 19 drwxr-xr-x 4 root root 4096 Jan 20 23:34 . drwxr-xr-x 4 root root 4096 Jan 20 23:34 .. drwxr-xr-x 6 root root 4096 Jan 20 23:34 cve-2025-60021 drwxr-xr-x 2 root root 4096 Jan 20 23:34 repo -rw-r--r-- 1 root root 503 Jan 20 23:34 trace.json -rw-r--r-- 1 root root 2029 Jan 20 23:34 trace_spans.jsonl
{"output":"{\"returncode\": 0, \"stdout\": \"total 19\\ndrwxr-xr-x 4 root root 4096 Jan 20 23:34 .\\ndrwxr-xr-x 4 root root 4096 Jan 20 23:34 ..\\ndrwxr-xr-x 6 root root 4096 Jan 20 23:34 cve-2025-60021\\ndrwxr-xr-x 2 ro"}ls -la /home/user/pruva/artifacts/runs/cve-2025-60021/20260120-233404/repototal 8 drwxr-xr-x 2 root root 4096 Jan 20 23:34 . drwxr-xr-x 4 root root 4096 Jan 20 23:34 ..
{"output":"{\"returncode\": 0, \"stdout\": \"total 8\\ndrwxr-xr-x 2 root root 4096 Jan 20 23:34 .\\ndrwxr-xr-x 4 root root 4096 Jan 20 23:34 ..\\n\", \"stderr\": \"\", \"cwd\": \"/home/user/pruva/artifacts/runs/cve-2025-60021/2"}ls -la /home/user/pruva/artifacts/runs/cve-2025-60021/20260120-233404/cve-2025-60021/artifacts/preppedtotal 8 drwxr-xr-x 2 root root 4096 Jan 20 23:34 . drwxr-xr-x 3 root root 4096 Jan 20 23:34 ..
{"output":"{\"returncode\": 0, \"stdout\": \"total 8\\ndrwxr-xr-x 2 root root 4096 Jan 20 23:34 .\\ndrwxr-xr-x 3 root root 4096 Jan 20 23:34 ..\\n\", \"stderr\": \"\", \"cwd\": \"/home/user/pruva/artifacts/runs/cve-2025-60021/2"}git --versiongit version 2.43.0
python3 --versionPython 3.11.14
curl --versioncurl 8.5.0 (x86_64-pc-linux-gnu) libcurl/8.5.0 OpenSSL/3.0.13 zlib/1.3 brotli/1.1.0 zstd/1.5.5 libidn2/2.3.7 libpsl/0.21.2 (+libidn2/2.3.7) libssh/0.10.6/openssl/zlib nghttp2/1.59.0 librtmp/2.3 OpenLDAP/2.6.7 Release-Date: 2023-12-06, security patched: 8.5.0-2ubuntu10.6 Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd
git clone https://github.com/apache/brpc.git /home/user/pruva/work/brpcCloning into '/home/user/pruva/work/brpc'...
{"output":"{\"returncode\": 0, \"stdout\": \"\", \"stderr\": \"Cloning into '/home/user/pruva/work/brpc'...\\n\", \"cwd\": \"/home/user/pruva/artifacts/runs/cve-2025-60021/20260120-233404/cve-2025-60021\"}"}Artifacts and Evidence for CVE-2025-60021
Scripts, logs, diffs, and output captured during the reproduction.
No artifacts available
How to Fix CVE-2025-60021
Upgrade brpc · cpp to 1.15.0 or later.
FAQ: CVE-2025-60021
How does the CVE-2025-60021 command injection attack work?
Which bRPC versions are affected by CVE-2025-60021, and where is it fixed?
How severe is CVE-2025-60021?
How can I reproduce CVE-2025-60021?
References for CVE-2025-60021
Authoritative sources for CVE-2025-60021 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.