How to Block Web Access to wp-content/upgrade in WordPress
Security Intermediate 4 min read

How to Block Web Access to wp-content/upgrade in WordPress

How to block wp-content/upgrade on nginx and Apache, test the rule and check logs, so WordPress core updates stop exposing a reachable staged install.

Published: November 4, 2026 • Updated: November 4, 2026
wordpressnginxapacheweb server hardening

To block wp-content/upgrade from web access, add a deny rule for that path in your nginx or Apache configuration, reload the server, and confirm that a request returns a denial. WordPress only needs filesystem access to the folder, so updates keep working. This closes the exposure behind CVE-2026-119977, the core update race, and it protects you during the last update to a fixed release.

Why block wp-content/upgrade at the web server?

WordPress unpacks updates into this folder, and on many servers the web server will serve whatever appears there. A rule at the web server applies before any PHP runs, so it also covers requests that a WordPress security plugin would never see.

Patchstack recommends this control for the WordPress upgrade race in CVE-2026-119977, because the extracted copy loads WordPress from its own files and bypasses a firewall inside the live site. The folder has no public purpose. Between updates, Patchstack says, it holds nothing but an index.php.

Do this before you update

Add the rule first if the site is not yet patched. Rescana notes that the update to 7.1.4 is still unpacked by the old code, so that final update can open the window once more. Patching first leaves that one run exposed.

Then update to 7.1.4 or the fixed release for your branch. The block does not replace the patch, since WordPress 7.1.4 also carries other security fixes.

How to block wp-content/upgrade on nginx

Add a prefix location inside the server block for the site:

location ^~ /wp-content/upgrade/ {
    deny all;
}

The ^~ modifier matters. The nginx documentation explains that when the longest matching prefix location has this modifier, regular expression locations are not checked. Many WordPress configurations include a regular expression location that passes .php files to PHP. Without the modifier, that location could win for a PHP request, and your deny rule would not apply to the file you most need to block.

Test the configuration and reload, using your normal process for that server. If WordPress runs in a subfolder, add the subfolder to the path. For example, a site at /blog/ needs /blog/wp-content/upgrade/.

How to block wp-content/upgrade on Apache

Add a section to the virtual host configuration, using the full filesystem path to the folder. Replace the document root in this example with your own:

<Directory "/usr/local/httpd/htdocs/wp-content/upgrade">
    Require all denied
</Directory>

The Apache documentation describes Require all denied as denying access unconditionally. The Directory section belongs in the server or virtual host configuration, not in .htaccess.

If you only control .htaccess, as on many shared hosts, put the rule in the site-root file. The right syntax depends on which modules your host allows, so ask the host for it and test the result.

Do not put the rule inside the upgrade folder

A .htaccess file inside wp-content/upgrade/ will not last on unpatched versions. Patchstack found that before 7.1.4, the cleanup routine deleted everything in that directory before each unpack. That includes any protection file you placed there, and it is the same step that removed the index.php.

Keep the rule in the server configuration or the site-root file, where the update process does not touch it.

Will blocking wp-content/upgrade break WordPress updates?

No. WordPress writes to this folder through the filesystem, not through web requests, so a web server deny rule does not stop it from unpacking updates. Test it anyway by running an update on a staging copy after you add the rule.

How do you confirm the block works?

Request a URL under /wp-content/upgrade/ from outside your network and confirm you get a denial, not a directory listing or PHP output. Then request a PHP filename at that path as well, because a rule that only covers the directory listing can still let PHP files run.

Make these checks part of the rollout:

  1. Test the bare folder URL and a PHP filename beneath it, using each hostname the site answers on.
  2. Test through your CDN or reverse proxy and, if you can, against the origin directly.
  3. Confirm the WordPress version. With WP-CLI, run the command below on each site, or use Dashboard, then Updates.
wp core version

The fixed releases are 7.1.4, 7.0.8, 6.9.11, 6.8.12, 6.7.11, 6.6.11, 6.5.14 and 6.4.14, with backports down to 4.7.39. Sites on 4.6 or older get no fix and need an upgrade to a supported release.

Hosted WordPress and other exceptions

On managed platforms you may not be able to edit web server rules. Ask the provider whether wp-content/upgrade/ is reachable and whether it has applied a platform mitigation. Pantheon, for example, deployed platform-wide mitigations for some of these flaws, while still telling customers to update.

Your path can also differ if the content directory was moved during a custom install. Check where the folder actually lives before you write the rule, and apply the same rule to every site in a multi-site host.

Check logs for earlier attempts

Search your access logs for PHP requests beneath wp-content/upgrade, then compare the times against your core update history. Wordfence also advises checking for unfamiliar administrator accounts, unexpected plugins and PHP files you did not place there. If you find them, follow our guide on cleaning a backdoored WordPress site.

The same approach applies to other upload and temporary paths. Our guide on blocking PHP execution in Magento media folders shows it on another platform. For the reasoning behind the flaw, read what a TOCTOU race condition is.