CVE-2026-39527

WpStream – Live Streaming, Video on Demand, Pay Per View < 4.11.2 - Authenticated (Subscriber+) Arbitrary File Upload

highUnrestricted Upload of File with Dangerous Type
8.8
CVSS Score
8.8
CVSS Score
high
Severity
4.11.2
Patched in
5d
Time to patch

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:H
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
High
Confidentiality
High
Integrity
High
Availability

Technical Details

Affected versions<4.11.2
PublishedApril 17, 2026
Last updatedApril 21, 2026
Affected pluginwpstream

What Changed in the Fix

Changes introduced in v4.11.2

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# 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:

  1. Perform a nonce check (CSRF protection).
  2. Perform a capability check (beyond being logged in).
  3. Restrict uploaded file types to safe extensions, relying on a call to wp_handle_upload with 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

  1. Entry Point: The AJAX action wp_ajax_wpstream_me_upload triggers the function wpstream_me_upload() in hello-wpstream/framework/ajax-upload.php.
  2. 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).
  3. Missing Nonce Check: Line 19: The code explicitly ignores nonce verification: //phpcs:ignore WordPress.Security.NonceVerification.Missing.
  4. File Preparation: Lines 19-25: The script takes the file from $_FILES['aaiu_upload_file'] and prepares it for processing.
  5. Processing: Calls wpstream_fileupload_process( $file, $button_id ).
  6. Handling: wpstream_fileupload_process calls wpstream_handle_file( $file, $button_id ).
  7. SINK: Line 96 in wpstream_handle_file():
    $uploaded_file = wp_handle_upload( $upload_data, array( 'test_form' => false ) );
    
    The test_form => false override 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
Research Findings
Static analysis — not yet PoC-verified

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

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/wpstream/4.11.1/hello-wpstream/framework/ajax-upload.php /home/deploy/wp-safety.org/data/plugin-versions/wpstream/4.11.2/hello-wpstream/framework/ajax-upload.php
--- /home/deploy/wp-safety.org/data/plugin-versions/wpstream/4.11.1/hello-wpstream/framework/ajax-upload.php	2025-07-29 05:15:40.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/wpstream/4.11.2/hello-wpstream/framework/ajax-upload.php	2026-03-16 07:07:36.000000000 +0000
@@ -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.