How BitFire Stops CVE-2026-18781 PHAR Upload Exploitation

WordPress vulnerability research

BitFire blocks malicious uploads and PRO RASP prevents unauthorized PHAR creation through the vulnerable Contact Form 7 add-on.

Unauthenticated Critical Severity Remote Code Execution Unrestricted File Upload
BitFire · Vulnerability advisoryResearch published
AdvisoryCVE-2026-18781
ComponentDrag and Drop Multiple File Upload for Contact Form 7
Relevant sourceinc/dnd-upload-cf7.php — dnd_upload_cf7_upload() filename pipeline
Executive summary

What WordPress administrators need to know

CVE-2026-18781 is a critical unauthenticated filename-validation flaw in Drag and Drop Multiple File Upload for Contact Form 7 before version 1.3.9.9. An attacker can obtain a nonce, then POST a PHAR polyglot whose filename hides `phar` with an interleaved control byte. Validation sees an allowed extension, but later filename normalization removes the byte and reconstructs a dangerous PHAR name before the file is written. Code execution then depends on the form and server stack or a reachable `phar://` file-operation sink. BitFire Bot Protection blocks restricted automated POST delivery, the WAF inspects and rejects malicious upload content, and BitFire PRO RASP prevents unauthorized PHAR archive creation at the filesystem boundary.

At a glance

Key facts

  • All versions before 1.3.9.9 are affected
  • The public admin-ajax.php upload path requires no WordPress account
  • A control byte hidden inside `phar` bypasses pre-normalization filename checks
  • Direct execution depends on form settings and the server PHP-handler configuration
  • Version 1.3.9.9 rejects control bytes and validates the final normalized filename
  • BitFire WAF blocks malicious uploads and PRO RASP prevents unauthorized PHAR creation
01
Vulnerability overview

Understand the exposure

The affected component, attack path, and practical risk for WordPress websites.

Affected componentDrag and Drop Multiple File Upload for Contact Form 7
Potential reach60,000 installations
Attack techniqueunrestricted file upload
Published2026-09-22
BitFire stops this exploit at three decisive boundaries: automated POST delivery, malicious upload inspection, and unauthorized PHAR creation on disk.
02
Technical analysis

How the vulnerability works

Research details, affected versions, exploitation behavior, and remediation guidance.

A Filename Mutation Reconstructs a Dangerous PHAR Archive

The plugin exposes `dnd_codedropz_upload` through unauthenticated `admin-ajax.php`; a companion action issues a usable nonce to anonymous callers, so no WordPress account is required. In version 1.3.9.8, the handler checks the multipart filename before Contact Form 7 removes control characters. A name with a control byte inside `phar` therefore passes the ASCII, blacklist, allowlist, and MIME-pattern checks as an allowed image. The final normalization silently removes that byte and writes `poc.phar.jpg`, or literal `poc.phar` when a form permits `filetypes:*`. Direct PHP execution requires a compatible Apache handler and ineffective upload-directory denial. The default `.jpg` result instead requires another attacker-influenced `phar://` file-operation sink and a viable POP chain. Those dependencies matter, but the upload still places an intact attacker-controlled PHAR on the server.

BitFire FREE Stops Automated Delivery and Malicious Upload Content

BitFire Bot Protection evaluates the client before the vulnerable plugin runs. Unknown or restricted automation cannot POST to the public AJAX actions, mint the nonce, or submit the multipart upload unless it is explicitly allowed; clients presenting as browsers must pass lightweight JavaScript verification. This blocks common scripted exploit delivery at the request boundary, while a verified browser or allowlisted integration still remains subject to later controls. The BitFire WAF then evaluates what the upload contains. Its malicious-upload inspection rejects web shells, executable PHP, malicious code, and other dangerous payloads before the vulnerable handler writes them. A weaponized PHAR polyglot carrying PHP and serialized exploit material crosses that inspection boundary. These request protections are available in BitFire FREE for eligible non-commercial sites; commercial use requires the appropriate license.

BitFire PRO RASP Prevents Unauthorized PHAR Creation

BitFire PRO RASP provides the independent runtime boundary that remains effective if a human-controlled client reaches the AJAX handler or an upload evades request filtering. Filesystem protection observes the attempted write and prevents an unauthenticated requester from creating the attacker-controlled PHAR archive. That blocks the dangerous on-disk primitive itself: there is no literal `.phar` for a permissive PHP handler to execute and no disguised `.phar.jpg` archive for a later `phar://` operation to parse. RASP does not repair the plugin's filename ordering or sanitize the supplied name. It denies the unauthorized filesystem outcome after request processing begins, preventing this vulnerable upload path from establishing executable PHP, a PHAR gadget payload, or a persistent backdoor.

Patch 1.3.9.9, Then Investigate for Persistence

Upgrade immediately to version 1.3.9.9 or later. The release rejects control and DEL bytes, moves anti-script normalization before extension extraction, validates the final filename that will be written, and hardens blacklist matching and dangerous-basename checks. The writeup also identifies residual separator-based PHAR reconstruction in 1.3.9.9, so administrators should retain layered upload and runtime protection rather than relying on filename validation alone. Patching does not remove an earlier compromise. Run BitFire Threat Hunter to find backdoor administrator accounts, hidden database triggers, long-running PHP processes, and droppers that can restore malware or reinfect the site. Remove discovered persistence, review upload and access logs, and rotate WordPress, hosting, database, and deployment credentials. An absent or auto-deleted upload does not prove the site is clean.

Block the Upload Chain Before It Becomes Code Execution

Sites running an affected release should update now and treat prior public upload exposure as an incident-response trigger. Deploy BitFire to enforce every meaningful boundary in this chain: Bot Protection denies restricted automated POST activity, the WAF rejects malicious upload payloads before plugin processing, and BitFire PRO RASP prevents unauthorized PHAR creation even when vulnerable code is reached. Then use Threat Hunter to investigate whether an attacker established another foothold during the exposure window. Patch the plugin, enable BitFire's layered protection, remove any persistence, and rotate relevant credentials rather than trusting server-specific execution restrictions as the only barrier.

03
Source review

Vulnerable and fixed code

The relevant source is located in inc/dnd-upload-cf7.php — dnd_upload_cf7_upload() filename pipeline.

BeforeVulnerable behavior
$extension = strtolower( pathinfo( $filename, PATHINFO_EXTENSION ) );

if ( ( ! preg_match( $file_type_pattern, $filename )
     || ! dnd_cf7_validate_type( $extension, $supported_type ) )
   && $supported_type != '*' ) {
    wp_send_json_error( $error_invalid_type );
}

// Dangerous mutation occurs after validation.
$filename = wpcf7_antiscript_file_name( $filename );
$new_file = path_join( $path['upload_dir'], $filename );
move_uploaded_file( $tmp_file, $new_file );
AfterCorrected behavior
// Reject control/DEL bytes.
$pattern = '/^[\x20-\x7E\p{L}\p{N}\p{M}\p{Z}\p{P}\p{Sc}]+$/u';

$filename = dnd_cf7_remove_icons( $filename );

// Normalize before extracting and validating the extension.
$filename = wpcf7_antiscript_file_name( $filename );
$extension = strtolower( pathinfo( $filename, PATHINFO_EXTENSION ) );

// Revalidate the exact filename that will be written.
$final_ext = strtolower( pathinfo( $filename, PATHINFO_EXTENSION ) );
if ( $supported_type == '*' && (
    in_array( $final_ext, $not_allowed_ext, true )
    || dnd_cf7_is_dangerous_filename( $filename )
) ) {
    wp_send_json_error( $error_invalid_type );
}
04
Zero-day protection

Protection from the first exploit request

BitFire protects WordPress servers on day zero—before a vulnerability is publicly known and before other vendors have time to develop signatures or patches.

01 · VerifyStop unknown clients

Bot controls and browser verification stop untrusted automated clients before previously unknown exploit code reaches WordPress.

02 · DetectBlock malicious behavior

General WAF protections identify dangerous request behavior and hostile payloads without waiting for a vulnerability-specific signature.

03 · PreventContain attacks at runtime

RASP follows execution inside PHP and prevents unauthorized changes to protected files, accounts, and database content.

BitFire · WordPress protectionZero-day ready
BitFire combines verified-client controls, behavior-based WAF detection, and runtime RASP enforcement to protect WordPress before an exploit has a name, CVE, signature, or vendor patch.
About the author

Cory Marsh

Cory has more than 20 years of internet security experience and is a lead developer on the BitFire project.

Read BitFire security research →
Protect your WordPress website

Add protection before the next exploit arrives.

BitFire combines bot controls, request inspection, malware detection, and runtime protection in one WordPress security platform.

Protect my site free →