PHP2Shell: what you can do right now

Two critical PHP vulnerabilities, nicknamed PHP2Shell (CVE-2026-109618 and CVE-2026-109619), let an attacker run code on a web server without logging in. PHP rates both 9.2 out of 10 and is shipping fixes on 21 October 2026 at 14:00 UTC. Details leaked a day early, and attacks have already been reported.

If your site runs on PHP, here is what you can do today, from the real fix to the stopgaps. For the full technical background and a live timeline, read Sansec’s advisory.

1. Update PHP as soon as you can

Updating PHP is the only real fix. Everything else in this article only lowers the risk until then.

  • Expected fixed versions: 8.5.12, 8.4.27, 8.3.36 and 8.2.35. These numbers come from security researchers and Linux distribution trackers; PHP itself only confirms them with the release.
  • Older versions (8.1, 8.0, 7.x, 5.x) are end of life and get no official fix. If you are on one of these, plan an upgrade now and keep the stopgaps below in place.
  • Check that your package really contains the fix. The version number alone can be misleading, because distributions often backport fixes. Look for the CVE number in the changelog, for example with apt changelog php8.3-cli (Debian/Ubuntu) or rpm -q --changelog php (RHEL/Alma/Rocky).
  • Restart PHP after updating (for example systemctl restart php8.3-fpm), otherwise the old code keeps running.
  • On shared hosting, ask your host when they will roll out the patched PHP version.

🤓😎 More and more people are getting our Geek, Privacy, Dev & Lifestyle Tips

Want to receive the latest Geek, Privacy, Dev & Lifestyle blogs? Subscribe to our newsletter.

2. Turn off session upload progress

Early analysis points to PHP’s session upload progress feature, which is on by default and kicks in when a file is uploaded. Turning it off and enabling strict session mode reduces your exposure. It does not fix the vulnerability, and security researchers warn it may block only one of the two bugs.

Add this to php.ini, .user.ini or your host’s PHP settings:

session.upload_progress.enabled = Off
session.use_strict_mode = 1

If you use PHP-FPM, you can also set it per pool:

php_admin_flag[session.upload_progress.enabled] = off

Reload PHP afterwards. Very few sites rely on upload progress bars built on this feature, so this change rarely breaks anything.

3. Block uploads on the web server (nginx)

The known attack paths use multipart requests, the format browsers use to upload files. Blocking those at the web server stops them before they reach PHP. Sansec recommends this as a temporary measure.

Add this inside your server { } block, outside any location:

if ($http_content_type ~* "multipart/form-data") {
    rewrite ^ /__upload_blocked last;
}

location = /__upload_blocked {
    internal;
    default_type text/plain;
    return 403 "Uploading is not allowed currently due to a big bug. Will be back soon.\n";
}

Visitors who try to upload now get a clear message instead of a bare error page. The internal line means nobody can open /__upload_blocked directly, and your other error pages stay the same.

Test and reload:

nginx -t && nginx -s reload
curl -i -F "x=1" https://yoursite.example/
curl -i -F "x=1" https://yoursite.example/some/subpage

Both curl tests should return 403 with the message. If a subpage still loads, check that the if sits directly in server { } and not inside a location, and that you edited the server block that actually serves the site. A normal page request without an upload should still work.

4. Block uploads on the web server (Apache / .htaccess)

On Apache 2.4, add this to the .htaccess in your document root. It works anywhere in the file, including above or below your CMS’s own rules:

<If "req('Content-Type') =~ m#multipart/form-data#i">
    ErrorDocument 403 "Uploading is not allowed currently due to a big bug. Will be back soon."
    Require all denied
</If>

Apache refuses the request before any rewrite rules run, so every URL is covered, not just the home page. A version based on RewriteRule [F] is easy to get wrong: placed below a CMS’s rules, it blocks only the home page while subpages still reach PHP.

  • Use the .htaccess Apache actually reads for your site. For Magento 2 that is often the one in pub/.
  • A subfolder with its own .htaccess, such as a second WordPress install, may need the same block.
  • A 500 error after saving usually means your host doesn’t allow these directives in .htaccess. Ask them to allow it or to add the rule in the server config.

Test the home page and at least one subpage. Both should return 403 with the message:

curl -i -F "x=1" https://yoursite.example/
curl -i -F "x=1" https://yoursite.example/some/subpage

If a subpage still returns the page itself, the block is not in effect for that URL.

What to expect, and when to undo it

The web server block stops every multipart request, not only file uploads. Expect these to stop working until you remove it:

  • File and image uploads, including in your admin area or CMS
  • Some ordinary forms, such as contact forms or product edits, that submit as multipart
  • Background uploads in JavaScript, which may show a generic error instead of your message

The PHP settings from step 2 rarely cause problems and can stay. Remove the web server block once PHP is updated and you have confirmed the fix in your package changelog. Then reload nginx or Apache and test an upload.

Further reading

Last Updated on 21 October 2026

Leave a Comment

Your email address will not be published. Required fields are marked *

en_USEnglish
Scroll to Top