Short answer: CVE-2026-114432 lets anyone who can see a Contact Form 7 form with a file field upload an arbitrary file to the site, with no account and no login. It affects Contact Form 7 6.2 through 6.2.3 and is fixed in 6.2.4. The score is 9.8, and the plugin has more than ten million installations. Whether that upload becomes remote code execution depends on two settings in your web server: whether directories are listable, and whether anything other than .php is routed to the PHP handler. Update the plugin first, then check those two things, because they decide the blast radius of every upload bug that follows this one.
What Goes Wrong
Contact Form 7 supports file fields so visitors can attach a CV or a photo. In the affected versions two separate problems line up.
First, the plugin does not validate the type or the extension of what arrives through that field. Second, its temporary-file cleanup has a flaw that leaves the uploaded file on disk instead of removing it after the submission is processed. Individually, either one would be a hardening issue. Together they mean an unauthenticated visitor can place a file of their choosing into the site's uploads area and have it persist there.
That is already bad: a file served from your domain carries your origin, your TLS certificate and your reputation. Whether it is worse than that depends entirely on your server configuration.
The Two Settings That Decide Severity
1. Is anything other than .php executed as PHP?
This is the detail that turns the advisory from serious into critical, and it catches people because it is a distribution default rather than something an administrator chose. The PHP configuration shipped for Apache on Debian and Ubuntu routes more than one extension to the PHP handler. The pattern it installs matches .php, .phar and .phtml:
grep -rn 'FilesMatch' /etc/apache2/ 2>/dev/null | grep -i 'ph'
grep -rn 'SetHandler\|AddHandler\|AddType' /etc/apache2/ 2>/dev/null | grep -i 'php'
If the output contains something like <FilesMatch ".+\.ph(ar|p|tml)$">, then a file called payload.phar in your uploads directory is not an inert archive. It is a script waiting for a request. On nginx the equivalent check is the location block that passes requests to PHP-FPM:
grep -rn 'location ~' /etc/nginx/ 2>/dev/null | grep -i 'php'
A pattern of \.php$ routes only one extension. A pattern of \.php without the anchor, or one that includes phar or phtml, routes more than you think.
2. Can an attacker see what they uploaded?
The uploaded file lands with a name the attacker does not fully control, so they need to find it again. Directory listing hands them that for free. On Apache, check for the option that enables it:
grep -rn 'Options' /etc/apache2/ 2>/dev/null | grep -i 'indexes'
You want to see -Indexes, not +Indexes and not a bare Indexes. On nginx, autoindex is off unless somebody turned it on:
grep -rn 'autoindex' /etc/nginx/ 2>/dev/null
Without listing, the attack is harder but not impossible, because WordPress itself exposes upload paths in several places. Treat listing as an amplifier you should remove, not as the only thing standing between you and the problem.
What to Do, in Order
- Update Contact Form 7 to 6.2.4 or later on every site. This is the fix; everything else is defence in depth.
wp plugin update contact-form-7 wp plugin list --name=contact-form-7 --field=version - Stop PHP from running inside the uploads directory. No legitimate WordPress upload needs to be executed. On Apache, a file at
wp-content/uploads/.htaccesscontaining the following removes the entire class of problem for that directory:
On nginx, the equivalent lives in the server block:<FilesMatch "\.(?i:php|phar|phtml|phps|php[0-9]*)$"> Require all denied </FilesMatch>location ~* ^/wp-content/uploads/.*\.(php|phar|phtml|phps)$ { deny all; } - Narrow the PHP handler to .php only if your configuration currently matches more. There is no common application that needs
.pharto be served over HTTP. - Turn off directory listing if it is on anywhere under a document root.
- Look for what may already be there. An upload that happened before you patched is still on disk:
Also check for HTML and SVG files that nobody in your team uploaded, since both are served as active content from your own origin and are the usual vehicle for phishing pages and stored cross-site scripting.find /home -path '*/wp-content/uploads/*' \ \( -name '*.php*' -o -name '*.phtml' -o -name '*.htaccess' \) \ -type f -newermt '2026-10-01' 2>/dev/null
Does This Affect a Panelica Server?
The plugin vulnerability affects any site running an unpatched Contact Form 7, on any panel and any stack, so the update is required regardless of where the site is hosted. What differs between hosts is the second half of the story: whether an uploaded file can be executed and how far it reaches if it is.
On Panelica, the two settings discussed above are decided by the virtual host the panel generates, and both are set the safe way:
- Directory listing is off. Generated virtual hosts carry
Options -Indexes, so an attacker cannot browse an uploads directory to locate what they placed there. - Only .php reaches PHP. The PHP handler is bound with a match on
\.php$and nothing else, so a.pharor.phtmlfile in a document root is served as a static file, not executed. The escalation path that the advisory describes for stock Apache configurations does not exist in the configuration the panel writes.
Two further properties limit what any executed code could do, which is the part worth thinking about for the next upload bug rather than this one. Each hosting account's websites run in their own PHP-FPM pool as their own system user, with open_basedir restricted to that account's home directory plus the read-only locations PHP needs, so a script cannot read another customer's files. And the process execution functions are disabled in the pool configuration: exec, passthru, shell_exec, system, proc_open and popen. A dropped PHP file therefore has no shell to reach for.
None of that is a reason to delay the plugin update. It is the reason a plugin bug on a well-configured server is an incident in one account instead of an incident on a server. If you are not sure which of your sites still run an old Contact Form 7, or whether every virtual host on your estate was generated with the same hardening, that visibility is what a panel is for. See how Panelica configures and isolates every hosting account.
A Note on the Pattern
Unauthenticated upload bugs in form plugins arrive every few months, and the reason they keep mattering is not the plugins. It is that many servers are configured so that a file appearing on disk is the same thing as code appearing on disk. Separating those two states is a one-time job: route a single extension to PHP, deny execution in writable directories, keep listing off, and run each site as its own user. Do it once and the next advisory in this family becomes a plugin update rather than a weekend.
Frequently Asked Questions
What is CVE-2026-114432?
It is an unrestricted file upload vulnerability in the Contact Form 7 WordPress plugin before 6.2.4. The plugin does not validate the type or extension of files submitted through a form file field, and a flaw in its temporary-file cleanup leaves the uploaded file on disk, so an unauthenticated visitor can store arbitrary files on the site. The CVSS v3.1 base score is 9.8.
Which Contact Form 7 versions are affected?
Versions 6.2 through 6.2.3. Update to 6.2.4 or later. Sites that do not use any file field in their forms are not exposed through this path, but there is no reason to stay on an affected version.
Does CVE-2026-114432 lead to remote code execution?
It can, on servers where the uploaded file can be executed. The reported escalation applies to stock Debian and Ubuntu Apache configurations that list directory contents and route .phar to the PHP handler in addition to .php. On configurations that execute only .php and do not list directories, the impact is an arbitrary file written into the uploads area, which can still be served as active content such as HTML or SVG from your own origin.
How do I check whether my server executes .phar files?
On Apache, run grep -rn 'FilesMatch' /etc/apache2/ | grep -i ph and look for a pattern that includes phar or phtml. On nginx, run grep -rn 'location ~' /etc/nginx/ | grep -i php and confirm the pattern is anchored as \.php$.
How do I block PHP execution in the WordPress uploads folder?
On Apache, place a .htaccess file in wp-content/uploads that denies requests matching PHP extensions. On nginx, add a location block that denies requests for PHP files under the uploads path. No legitimate upload needs to be executed, so this costs nothing and neutralises this entire class of bug for that directory.
I patched the plugin. Could a file already be on my server?
Yes, if the site was exposed before the update. Search the uploads directories for recently created files with PHP, phar, phtml or htaccess names, and for HTML and SVG files your team did not upload. Both of the latter are served as active content from your domain.
Are nginx servers safe from this?
Safer, not safe. nginx does not list directories by default and typical configurations route only .php to PHP-FPM, which removes the straightforward code execution path. The arbitrary file is still written, and an HTML or SVG file served from your origin is enough for phishing or stored cross-site scripting. Update the plugin either way.