WpStream – Live Streaming, Video on Demand, Pay Per View < 4.11.2 - Authenticated (Subscriber+) Arbitrary File Upload
Description
The WpStream – Live Streaming, Video on Demand, Pay Per View plugin for WordPress is vulnerable to arbitrary file uploads due to missing file type validation in all versions up to 4.11.2 (exclusive). This makes it possible for authenticated attackers, with Subscriber-level access and above, to upload arbitrary files on the affected site's server which may make remote code execution possible.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HTechnical Details
What Changed in the Fix
Changes introduced in v4.11.2
Source Code
WordPress.org SVN# CVE-2026-39527: WpStream Arbitrary File Upload Research Plan ## 1. Vulnerability Summary The **WpStream** plugin for WordPress (versions up to 4.11.2) is vulnerable to an **Authenticated Arbitrary File Upload** vulnerability. The vulnerability exists in the `wpstream_me_upload` AJAX action handle…
Show full research plan
CVE-2026-39527: WpStream Arbitrary File Upload Research Plan
1. Vulnerability Summary
The WpStream plugin for WordPress (versions up to 4.11.2) is vulnerable to an Authenticated Arbitrary File Upload vulnerability. The vulnerability exists in the wpstream_me_upload AJAX action handler located in hello-wpstream/framework/ajax-upload.php.
The handler fails to:
- Perform a nonce check (CSRF protection).
- Perform a capability check (beyond being logged in).
- Restrict uploaded file types to safe extensions, relying on a call to
wp_handle_uploadwith insufficient overrides, which in the context of this plugin's configuration allows dangerous file types (like.php) to be uploaded by users with Subscriber-level permissions.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
wpstream_me_upload - Method:
POST(multipart/form-data) - Authentication: Required (Subscriber or higher)
- Vulnerable Parameter:
aaiu_upload_file(file upload field) - Preconditions: None, other than a valid Subscriber account.
3. Code Flow
- Entry Point: The AJAX action
wp_ajax_wpstream_me_uploadtriggers the functionwpstream_me_upload()inhello-wpstream/framework/ajax-upload.php. - Authentication Check: Line 15:
if ( ! is_user_logged_in() ) { exit( 'ko' ); }. This ensures only authenticated users can proceed, but fails to check for specific capabilities (e.g.,upload_files). - Missing Nonce Check: Line 19: The code explicitly ignores nonce verification:
//phpcs:ignore WordPress.Security.NonceVerification.Missing. - File Preparation: Lines 19-25: The script takes the file from
$_FILES['aaiu_upload_file']and prepares it for processing. - Processing: Calls
wpstream_fileupload_process( $file, $button_id ). - Handling:
wpstream_fileupload_processcallswpstream_handle_file( $file, $button_id ). - SINK: Line 96 in
wpstream_handle_file():
The$uploaded_file = wp_handle_upload( $upload_data, array( 'test_form' => false ) );test_form => falseoverride instructs WordPress to skip the verification of the POST submission origin. Because the plugin does not provide a restricted list of allowed MIME types in the overrides, it relies on the global configuration which, in the case of this vulnerable plugin, allows Subscriber-level
Summary
The WpStream plugin for WordPress is vulnerable to arbitrary file uploads via the wpstream_me_upload AJAX action. Authenticated users with subscriber-level permissions can upload dangerous file types, including PHP scripts, because the plugin fails to perform nonce checks, capability checks, or restrict uploaded file extensions, potentially leading to remote code execution.
Vulnerable Code
// hello-wpstream/framework/ajax-upload.php:12 function wpstream_me_upload() { if ( ! is_user_logged_in() ) { exit( 'ko' ); } $button_id = isset( $_POST['button_id'] ) ? sanitize_text_field( $_POST['button_id'] ) : ''; $file = array( //phpcs:ignore WordPress.Security.NonceVerification.Missing 'name' => isset( $_FILES['aaiu_upload_file']['name'] ) ? sanitize_file_name( $_FILES['aaiu_upload_file']['name'] ) : '', 'type' => $_FILES['aaiu_upload_file']['type'], 'tmp_name' => $_FILES['aaiu_upload_file']['tmp_name'], 'error' => $_FILES['aaiu_upload_file']['error'], 'size' => $_FILES['aaiu_upload_file']['size'], ); wpstream_fileupload_process( $file, $button_id); } --- // hello-wpstream/framework/ajax-upload.php:94 function wpstream_handle_file( $upload_data, $button_id = '' ) { $return = false; $uploaded_file = wp_handle_upload( $upload_data, array( 'test_form' => false ) ); if ( isset( $uploaded_file['file'] ) ) { $file_loc = $uploaded_file['file']; $file_name = basename( $upload_data['name'] ); $file_type = wp_check_filetype( $file_name ); $attachment = array( 'post_mime_type' => $file_type['type'], 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $file_name ) ), 'post_content' => '', 'post_status' => 'inherit', );
Security Fix
@@ -10,8 +10,10 @@ * Handles AJAX request for file upload. */ function wpstream_me_upload() { - if ( ! is_user_logged_in() ) { - exit( 'ko' ); + check_ajax_referer( 'aaiu_allow', 'nonce' ); + + if ( ! is_user_logged_in() || ! current_user_can( 'upload_files' ) ) { + wp_send_json_error( array( 'message' => 'You are not allowed to upload files.' ), 403 ); } $button_id = isset( $_POST['button_id'] ) ? sanitize_text_field( $_POST['button_id'] ) : ''; @@ -24,7 +26,7 @@ 'size' => $_FILES['aaiu_upload_file']['size'], ); - wpstream_fileupload_process( $file, $button_id); + wpstream_fileupload_process( $file, $button_id ); }
Exploit Outline
To exploit this vulnerability, an attacker must first obtain subscriber-level credentials. Using an authenticated session, the attacker sends a multipart/form-data POST request to the WordPress AJAX endpoint (/wp-admin/admin-ajax.php) with the 'action' parameter set to 'wpstream_me_upload'. The malicious payload is placed in the 'aaiu_upload_file' parameter, which can contain a PHP script (e.g., shell.php). Because the plugin lacks a capability check (current_user_can('upload_files')) and does not verify nonces, the server processes the file via wp_handle_upload() with the 'test_form' check disabled. This allows the attacker to place a PHP file on the server and subsequently access it to execute arbitrary code.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.