CVE-2026-16527 - Performance Co-Pilot

CVE-2026-16527 - Performance Co-Pilot (PCP)

Vulnerability Description: CWE-306: Missing Authentication for Critical Function

Software Version: 7.1.3

CVSS: 7.3

Severity:  High

NVD: https://nvd.nist.gov/vuln/detail/cve-2026-16527

Credits: Francisco Alisson Bezerra, Lucas Gabriel Alves, Massimiliano Brolli

The pmproxy REST API exposes a /store endpoint writing to any PMDA metric via pmStore() without authentication. Two authentication flags (-S for credential requirements, -Q for client certificate) exist as case blocks in the source but are absent from the short_options string and longopts table, making both code paths permanently dead and impossible to activate. Combined with an unrestricted hostspec parameter, an unauthenticated HTTP attacker can force pmproxy to connect to pmcd via Unix socket, bypassing all pmcd [access] host rules that cover only IPv4 and IPv6 transports.

Prerequisites: pmproxy running and reachable on default port 44322. pmcd running. linux_sockets PMDA loaded (required for the full RCE chain with CVE-2026-16524).

Step-by-step Instructions and PoC

pmproxy exposes a REST API including a /store endpoint that writes to any PMDA metric via pmStore(). Two authentication flags exist in the source: -Q (require trusted client certificate) and -S (require authenticated credentials). Both are implemented as case blocks in the option switch, but neither character ('Q' nor 'S') appears in the short_options string or in the longopts table. This makes both code paths permanently dead - the flags cannot be activated at runtime.

The vulnerability is compounded by an unrestricted hostspec parameter in the /context endpoint. An attacker can specify hostspec=local: to force pmproxy to connect to pmcd via Unix socket. Unix socket connections bypass all [access] ACL rules in pmcd.conf, which only apply to IPv4 and IPv6 transports. Combined with Vulnerability 3, this produces unauthenticated remote code execution from any host reaching pmproxy on TCP 44322.

Affected Source Files and Lines

src/pmproxy/src/pmproxy.c:96-105: pmOptions short_options at line 98 - 'Q' and 'S' absent

src/pmproxy/src/pmproxy.c:190-215: case 'Q' at line 193 and case 'S' at line 210 - permanently dead code

Image 1 - pmproxy.c:98 (highlighted). short_options string does not include 'Q' or 'S'.

Click to Enlarge

Image 2 - pmproxy.c:193 and 210 (highlighted). Both case blocks exist but are unreachable.

Click to Enlarge

Affected Endpoints

URL (TCP 44322): GET /pmapi/context?hostspec=local:

URL (TCP 44322): POST /pmapi/{ctx}/store?name=network.persocket.filter

URL (TCP 44322): GET /pmapi/{ctx}/fetch?names=network.persocket

The missing authentication is demonstrated using poc.py, which performs the full three-step exploit chain (context creation, metric store, fetch) against the default pmproxy installation without supplying any credentials. All three HTTP requests succeed with HTTP 200, confirming that the API accepts write operations from unauthenticated remote clients on port 44322.

Image 3 - PMCD configuration, blocking store from IPV4 and IPV6.

Click to Enlarge

Image 4 - Temp folder before the exploit execution.

Click to Enlarge

Image 5 - Execution of the proof-of-concept script.

Click to Enlarge

Image 6 - poc_rce.txt file created in temp folder after executing the proof-of-concept.

Click to Enlarge

Security Impact

  • Combined with CVE-2026-16524 (inverted guard in linux_sockets PMDA), this produces unauthenticated remote code execution accessible from any host reaching pmproxy TCP port 44322, with no local access required.
  • Unauthenticated HTTP clients can read any PCP metric and write to any PMDA accepting pmStore().