CVE-2026-47990 Adobe Experience Manager

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

Vulnerability Description: CWE-78: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

Software Version: 7.1.3

CVSS: 7.8

Severity:  High

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

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

A command injection vulnerability exists in the linux_sockets PMDA through the writable metric network.persocket.filter. The validation helper sockets_check_filter() returns 1 for safe input and 0 for unsafe input, but the store handler uses an inverted condition: safe expressions are rejected while malicious ones containing shell metacharacters are silently accepted. The attacker-controlled filter value is later incorporated into a shell command executed via popen() whenever socket metrics are refreshed, enabling arbitrary command execution as the PMDA process user.

Prerequisites:

  • linux_sockets PMDA loaded;
  • ss binary present (/usr/sbin/ss or /usr/bin/ss);
  • no [access] section restricting pmstore in pmcd.conf (default behavior).

Observation: pmcd (TCP 44321) binds to localhost only by default (PMCD_LOCAL=1 in /etc/default/pmcd on Debian/Ubuntu), limiting direct exploitation to local access. However, pmproxy (TCP 44322) binds to all interfaces by default (PMPROXY_LOCAL unset) and exposes an unauthenticated HTTP REST API that internally calls pmStore()/pmFetch(), enabling full remote exploitation without any local access. 

Step-by-step instructions and PoC

The linux_sockets PMDA collects socket-level metrics by spawning the system ss utility and parsing its output. It exposes the writable metric network.persocket.filter that allows operators to set BPF filter expressions passed without sanitization to ss. The vulnerability originates from a logic inversion in the store handler: sockets_check_filter() returns 1 for safe input and 0 for input containing shell metacharacters. The guard in sockets_store() tests if (sockets_check_filter(av.cp)), which causes safe input to be rejected and malicious input to pass unchecked into popen(). Because popen() invokes /bin/sh, any shell metacharacter embedded in the filter is executed as an OS command with the privileges of the PMDA process (typically user pcp).

Affected Source Files and Lines

src/pmdas/linux_sockets/pmda.c:160-176: sockets_check_filter() - correct logic, safe=1 / unsafe=0

src/pmdas/linux_sockets/pmda.c:188-200: sockets_store() - inverted guard: line 194 is the root cause

src/pmdas/linux_sockets/ss_stream.c:43-55: ss_open_stream() - popen() execution sink at lines 48-49

Image 1 - sockets_check_filter() (pmda.c:160). Returns 1 for safe input and 0 for metacharacters - correct logic.

Click to Enlarge

Image 2 - Inverted guard in sockets_store() (pmda.c:194, highlighted). Safe input is rejected; payload with metacharacters is accepted.

Click to Enlarge

Image 3 - Execution sink in ss_open_stream() (ss_stream.c:48-49). Attacker-controlled ss_filter is passed directly to popen().

Click to Enlarge

Affected Endpoints

pmcd TCP 44321 (localhost only by default): network.persocket.filter via pmstore

pmproxy TCP 44322 (all interfaces by default): POST /pmapi/{ctx}/store - no authentication

The proof-of-concept (poc.py) sends three unauthenticated HTTP requests to pmproxy (port 44322): it opens a context via GET /pmapi/context, stores a shell metacharacter payload (;id>/tmp/poc_rce_sockets.txt;echo) to network.persocket.filter via POST, then fetches network.persocket.netid to trigger execution. The linux_sockets PMDA passes the filter value verbatim to popen(), running the injected command as user pcp. Successful execution is confirmed by the output file created on the target.

Image 4 - Files in temp folder before the exploit execution.

Click to Enlarge

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

Click to Enlarge

Image 6 - poc_rce_sockets.txt created in temp folder.

Click to Enlarge

 

Security Impact

  • An unauthenticated remote attacker can execute arbitrary commands as the PMDA process user (typically pcp), potentially achieving remote code execution, persistence, lateral movement, or privilege escalation.
  • The vulnerability is remotely exploitable on default installations via the pmproxy HTTP REST API (port 44322, bound to all interfaces, no authentication required), bypassing the localhost-only restriction of pmcd (port 44321).
  • Successful exploitation allows arbitrary operating system command execution.