PHP2Shell Vulnerability (CVE-2026-109618 and CVE-2026-109619) on AWS: How to Patch PHP on Lightsail WordPress, Elastic Beanstalk, Amazon Linux 2023, Ubuntu, Containers and Lambda, Plus the AWS WAF Rules to Use While You Patch

Logeshwaran
—

The PHP2Shell vulnerability is the name for two critical PHP flaws, CVE-2026-109618 and CVE-2026-109619, that let an attacker run code on a PHP web server without logging in. They are fixed in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, released on October 21, 2026, and PHP 8.1 and older get no fix at all. On AWS, the fix depends on where your PHP runs: apt upgrade on Lightsail WordPress and LAMP, a new platform version (4.13.13) on Elastic Beanstalk, a rebuilt image for containers, composer update bref/bref -W for Lambda, and on Amazon Linux 2023 a dnf command with one extra option. That option is the trap: on an Amazon Linux 2023 server from late September running PHP 8.4.25, a plain dnf check-update reported nothing to update, while the fixed 8.4.27 sat one release version away.

Jake's shop website runs WordPress on a small Lightsail server, and the morning the news broke he asked Ethan the only question he cared about: "Are we one of the people who need to worry?" Ethan logged in, typed one command and said yes. Then he showed Jake something worse. The first attack attempts on decoy servers had been recorded on October 17, four days before anyone outside the PHP security team knew the bug existed. "So patching today is the job," Ethan said, "and checking the logs back to the seventeenth is the other job."

⚡ Quick Answer

Status on October 23, 2026: fixed PHP is available on every AWS path below, and exploitation attempts are ongoing.

• Fixed versions: PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35. Anything older on those lines is affected; 8.1 and older have no fix. One-paste check.

• Amazon Linux 2023 (EC2): sudo dnf update --releasever 2023.12.20261021 'php8*', then restart PHP-FPM. Without the release version, dnf may find nothing. Why.

• Lightsail WordPress, LAMP, Nginx: sudo apt update && sudo apt upgrade, restart the web server. Bitnami instances need more. Steps.

• Elastic Beanstalk: move to platform 4.13.13. How. Containers: rebuild on php:8.4.27 or newer. How. Lambda (Bref): composer update bref/bref -W and redeploy. How.

• Can't patch this hour? AWS WAF PHP rule group version 2.3 plus a body-size rule narrow the risk; they do not close it. Rules.

What PHP2Shell is · Which AWS setups are affected · Amazon Linux 2 · php.ini stopgaps · Were you already attacked? · Many servers at once · FAQ.

This guide is for anyone running PHP on AWS, from a single WordPress blog on Lightsail to a fleet of PHP containers behind a load balancer. It explains the two bugs in plain English, then walks through the exact fix for each AWS service in the order most people need them. If you only have five minutes, run the one-paste check, then jump to the section for your setup.

🧭 NEW HERE? READ THESE FIRST

New to these AWS services? These pages explain the basics this guide uses:

💡 The fix is a PHP update. The AWS part is knowing which update command your service needs, and restarting the right thing afterwards.

PHP2Shell explained: what it is and how PHP2Shell works

PHP2Shell is two separate bugs found in the core of PHP itself, not in WordPress, Laravel or any plugin. That is why it is so serious: your own code can be perfect and the server is still exposed, because the problem happens while PHP is reading the incoming request, before your application code runs. Both bugs are rated 9.2 out of 10 (Critical) on the newest scoring system, CVSS 4.0. Amazon Linux rates them 8.1, Important, on the older CVSS 3.1 scale, which is why you will see two different scores for the same flaws.

  • CVE-2026-109618, "out-of-memory corruption": when PHP runs out of memory while it is still setting up a request, it can leave some internal data half-built. The cleanup that runs at the end of the request then treats that broken data as real. An attacker can push PHP into that out-of-memory moment on purpose with a specially shaped file-upload request (the multipart/form-data format browsers use for uploads), even on a page that has no upload form at all.
  • CVE-2026-109619, "stale state": PHP keeps a few bits of information between requests in the same worker process. If one request is interrupted at the wrong moment, a pointer to its memory survives after that memory is freed, and the next request handled by the same worker can use it. One confirmed way to trigger it goes through a little-used feature called session upload progress; on PHP 8.5 another goes through the fatal_error_backtraces setting.

Both lead to the same place: the attacker's code running on your server with the permissions of the web server account, which can usually read your site's files, its database password and anything else the web server can reach. The PHP security advisory lists every way PHP serves web pages as affected: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed, with the risk highest for mod_php, where the full attack was demonstrated with default memory and upload limits. PHP scripts that only run from the command line (cron jobs, queue workers) are not in the described attack paths, because they do not parse web requests, but they use the same engine, so update them in the same pass.

The flawed code is old. Every PHP line back to 5.4, released in 2012, is affected, so the underlying bugs are more than a decade old, which is why some reports call PHP2Shell a decade-old bug. This page leaves out the exploit details. For defending a server, what matters is which version you run and how to change it, and that is the rest of this guide.

Jake: "So it's not WordPress. It's the thing underneath WordPress."

Ethan: "Right. Updating plugins won't touch it. This one is a PHP update."

The timeline, and why the date you check from matters

Date (UTC)What happened
October 17, 2026An exploitation attempt hits Amazon's MadPot decoy servers, from an anonymizing network, four days before public disclosure.
October 20The PHP project announces a critical security release for the next day at 14:00 UTC. Details start leaking early.
October 21, about 02:00Proof-of-concept exploits appear, and more attempts against decoy servers follow from several groups.
October 21, 13:35PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 are published. Bref's Lambda layers follow 31 minutes later. AWS publishes security bulletin 2026-143-AWS and a WAF rule update.
October 21 to 22Fixed packages for Amazon Linux 2023 (ALAS2023-2026-3301 to 3304) and Amazon Linux 2's PHP 8.2 extra, new Elastic Beanstalk platforms, updated Lightsail blueprints and official Docker php images.

The practical lesson is in the first row. If your server was exposed, an attack may predate the news, so when you look for signs of trouble, look back to at least October 17, not October 21. Amazon's threat intelligence team gives exactly that advice, and also warns that the gap between a patch and a working exploit is now measured in hours. A "we patch critical issues within 7 days" policy was written for a slower world.

Which AWS setups are affected: the one-table answer

AWS itself is not affected; its own services that used PHP were patched by AWS. What is affected is any PHP you run on AWS. This table lists every common setup and who has to act:

Where your PHP runsWho patchesThe fix
EC2 with Amazon Linux 2023 (php8.2 to php8.5 packages)Youdnf update with --releasever 2023.12.20261021, restart PHP-FPM or Apache
EC2 with Amazon Linux 2, PHP 8.2 from ExtrasYouyum update php (advisory ALAS2PHP8.2-2026-015)
EC2 with Amazon Linux 2, the built-in php packageNobody: no fix plannedMove to PHP 8.2+ from Extras, or better, to Amazon Linux 2023
EC2 with Ubuntu or DebianYouapt upgrade, then restart; Ubuntu keeps the old version number (fixed packages)
Lightsail WordPress, WordPress Multisite, LAMP, Nginx (Lightsail-packaged)Youapt update + apt upgrade, restart the web server
Lightsail Bitnami blueprints (WordPress, LAMP and other PHP apps)YouMove to a Lightsail-packaged blueprint, or switch the Bitnami web server to a package-managed PHP
Elastic Beanstalk PHP platformsAWS, if managed updates are on; otherwise youPlatform version 4.13.13 (AL2023, PHP 8.2 to 8.5)
Containers on ECS, EKS, App RunnerYouRebuild on a fixed base image, push, redeploy
Lambda with BrefYou (Bref publishes the layers)composer update bref/bref -W, redeploy
Lambda with your own PHP custom runtimeYouRebuild the runtime with a fixed PHP, redeploy
Amazon WorkMailAWS (done)Nothing to do

You can stop worrying if none of your servers run PHP at all: a static website on S3 and CloudFront, a Node.js, Python, Java or .NET application, Lightsail Node.js or Ruby on Rails blueprints, or Lambda functions in other languages are not touched by PHP2Shell. Neither are sites on managed services where the provider runs PHP for you, such as Amazon WorkMail. If you are not sure whether a server has PHP, the one-paste check below tells you in seconds.

Lambda has no managed PHP runtime, so there is no AWS-side switch for it: whatever PHP you packaged is what runs until you rebuild. Lightsail cannot update running instances for you either. The new blueprints only help servers created from now on.

Check your PHP version in one minute

Connect to the server (on Lightsail, the browser-based SSH button is fine) and run:

php -v

The first line is what matters, for example PHP 8.4.25 (cli) .... Compare it with the table: on the 8.5 line you need 8.5.12 or newer, on 8.4 you need 8.4.27, on 8.3 you need 8.3.36, and on 8.2 you need 8.2.35. Anything on 8.1, 8.0, 7.x or 5.x is affected with no upstream fix.

PHP lineAffectedFirst fixed versionStatus
8.58.5.0 to 8.5.118.5.12Supported
8.48.4.0 to 8.4.268.4.27Supported
8.38.3.0 to 8.3.358.3.36Supported
8.28.2.0 to 8.2.348.2.35Security fixes until December 31, 2026
8.1 and older (back to 5.4)AllNoneEnd of life: migrate

Three catches. On Ubuntu, a patched server keeps its old-looking version number, so read the Ubuntu section before you panic. On Bitnami Lightsail instances the web server uses its own PHP, so check /opt/bitnami/php/bin/php -v instead. And php -v only shows the command-line PHP. A server can have several PHP versions installed, and the web server can use a different one from the terminal. To see the PHP that actually serves your site, put a temporary file in the web root, request it and delete it straight away:

echo '<?php echo PHP_VERSION, " ", PHP_SAPI;' | sudo tee /var/www/html/v.php > /dev/null
curl -s http://localhost/v.php; echo
sudo rm -f /var/www/html/v.php

It prints something like 8.4.27 fpm-fcgi. Change /var/www/html if your site lives elsewhere. On WordPress you can also open Tools, Site Health, Info, Server in the dashboard and read the PHP version there.

One paste: is this server fixed?

If you would rather have a straight answer than compare version numbers, this short read-only script checks every PHP it can find on a Linux server, reads the right version number for Amazon Linux, Ubuntu, Debian, Alpine and Bitnami, and looks for running PHP workers that still have the old code in memory. Save it as php2shell-check.sh (for example with nano php2shell-check.sh and paste), then run sudo sh php2shell-check.sh.

#!/bin/sh
# php2shell-check.sh - is the PHP on this server fixed for PHP2Shell (CVE-2026-109618, CVE-2026-109619)?
# Read-only. Run with sudo so it can see every PHP process.   Version 2026-10-23
fixed_patch() { case "$1" in 8.5) echo 12;; 8.4) echo 27;; 8.3) echo 36;; 8.2) echo 35;; *) echo "";; esac; }
ubuntu_fixed() { case "$1" in   # Ubuntu backports fixes without changing the PHP version number
  php8.5:26.10) echo 8.5.9-0ubuntu2.1;; php8.5:26.04) echo 8.5.4-0ubuntu1.5;;
  php8.3:24.04) echo 8.3.6-0ubuntu0.24.04.13;; php8.1:22.04) echo 8.1.2-1ubuntu2.28;;
  php7.4:20.04) echo 7.4.3-4ubuntu2.29+esm5;; *) echo "";; esac; }
. /etc/os-release 2>/dev/null
echo "PHP2Shell check on ${PRETTY_NAME:-unknown OS}"
[ "$ID" = amzn ] && [ -f /etc/system-release ] && echo "  release: $(cat /etc/system-release)"
seen=""; bad=0; found=0
for bin in $(command -v php 2>/dev/null) /usr/bin/php /usr/bin/php[0-9]* /usr/local/bin/php /opt/bitnami/php/bin/php \
           /usr/sbin/php-fpm /usr/sbin/php-fpm[0-9]* /usr/local/sbin/php-fpm /opt/bitnami/php/sbin/php-fpm; do
  [ -x "$bin" ] || continue
  real=$(readlink -f "$bin"); case " $seen " in *" $real "*) continue;; esac; seen="$seen $real"
  ver=$("$bin" -v 2>/dev/null | head -1 | sed -n 's/^PHP \([0-9]*\.[0-9]*\.[0-9]*\).*/\1/p'); [ -n "$ver" ] || continue
  found=1; line=${ver%.*}; patch=${ver##*.}; verdict=""; pkg=""; need=""; pv=""
  if [ "$ID" = ubuntu ] && command -v dpkg >/dev/null && pkg=$(dpkg -S "$real" 2>/dev/null | cut -d: -f1 | head -1) && [ -n "$pkg" ]; then
    pv=$(dpkg-query -W -f='${Version}' "$pkg"); src="php$line"; need=$(ubuntu_fixed "$src:$VERSION_ID")
  fi
  if [ -n "$pkg" ] && [ -n "$need" ]; then
    if dpkg --compare-versions "$pv" ge "$need"; then verdict="FIXED (Ubuntu package $pv)"
    else verdict="NOT FIXED: package $pv, needs $need or newer (sudo apt update && sudo apt upgrade)"; bad=1; fi
  else
    need=$(fixed_patch "$line")
    if [ -z "$need" ]; then verdict="NO UPSTREAM FIX: PHP $line is end of life - upgrade to 8.2+ (or a vendor backport)"; bad=1
    elif [ "$patch" -ge "$need" ]; then verdict="FIXED"
    else verdict="NOT FIXED: needs $line.$need or newer"; bad=1; fi
  fi
  case "$real" in /opt/bitnami/*) verdict="$verdict  [Bitnami copy: apt upgrade does not update it]";; esac
  echo "  $real  PHP $ver  ->  $verdict"
done
[ $found = 1 ] || echo "  no PHP binary found in the usual places (containers: run this inside the container)"
if [ "$ID" = amzn ] && [ "$VERSION_ID" = 2023 ] && [ $bad = 1 ] && command -v dnf >/dev/null; then
  echo "  Amazon Linux 2023: plain 'dnf update' looks only inside your release. The fix:"
  echo "    sudo dnf update --releasever 2023.12.20261021 'php8*'   then: sudo systemctl restart php-fpm httpd"
fi
# a running PHP worker keeps the old code in memory until it restarts: look for deleted (replaced) binaries/modules
for p in /proc/[0-9]*; do
  exe=$(readlink "$p/exe" 2>/dev/null) || continue
  case "$exe" in *php*|*httpd*|*apache2*|*frankenphp*|*lsphp*) ;; *) continue;; esac
  if case "$exe" in *" (deleted)") true;; *) grep -q 'php.*(deleted)' "$p/maps" 2>/dev/null;; esac; then
    echo "  RESTART NEEDED: process ${p#/proc/} ($exe) still runs the PHP it started with"; bad=1
  fi
done
if [ $found = 0 ]; then echo "RESULT: nothing to check"
elif [ $bad = 0 ]; then echo "RESULT: no vulnerable PHP found"
else echo "RESULT: action needed (see above)"; fi

On an Amazon Linux 2023 server still on PHP 8.4.25, it names the problem and the fix:

$ sudo sh php2shell-check.sh
PHP2Shell check on Amazon Linux 2023.12.20260930
  release: Amazon Linux release 2023.12.20260930 (Amazon Linux)
  /usr/bin/php  PHP 8.4.25  ->  NOT FIXED: needs 8.4.27 or newer
  /usr/sbin/php-fpm  PHP 8.4.25  ->  NOT FIXED: needs 8.4.27 or newer
  Amazon Linux 2023: plain 'dnf update' looks only inside your release. The fix:
    sudo dnf update --releasever 2023.12.20261021 'php8*'   then: sudo systemctl restart php-fpm httpd
RESULT: action needed (see above)

After the update, but before PHP-FPM was restarted, it catches the worker that still runs the old code from memory, the step most people forget:

$ sudo sh php2shell-check.sh
PHP2Shell check on Amazon Linux 2023.12.20260930
  release: Amazon Linux release 2023.12.20260930 (Amazon Linux)
  /usr/bin/php  PHP 8.4.27  ->  FIXED
  /usr/sbin/php-fpm  PHP 8.4.27  ->  FIXED
  RESTART NEEDED: process 199 (/usr/sbin/php-fpm (deleted)) still runs the PHP it started with
RESULT: action needed (see above)

And on Ubuntu 24.04 it reads the package revision instead of the misleading version number, first on the original release package, then on the patched one:

$ sudo sh php2shell-check.sh
PHP2Shell check on Ubuntu 24.04.5 LTS
  /usr/bin/php8.3  PHP 8.3.6  ->  NOT FIXED: package 8.3.6-0maysync1, needs 8.3.6-0ubuntu0.24.04.13 or newer (sudo apt update && sudo apt upgrade)
RESULT: action needed (see above)

$ sudo apt update && sudo apt upgrade && sudo sh php2shell-check.sh
PHP2Shell check on Ubuntu 24.04.5 LTS
  /usr/bin/php8.3  PHP 8.3.6  ->  FIXED (Ubuntu package 8.3.6-0ubuntu0.24.04.13)
RESULT: no vulnerable PHP found

It changes nothing on the server, so it is safe to run on production. To run it on many EC2 servers at once, open Systems Manager, choose Run Command, pick the AWS-RunShellScript document and paste the whole script into its Commands box (more in the fleet section). For a container, run it inside the container, for example docker exec -i my-container sh < php2shell-check.sh.

EC2 with Ubuntu or Debian: why "PHP 8.3.6" can be the fixed version

If your EC2 server runs Ubuntu, the version check above can mislead you. Ubuntu fixes security bugs by patching the PHP version it shipped, without moving to the new upstream number. A fully patched Ubuntu 24.04 server still prints PHP 8.3.6, nowhere near 8.3.36, and the fix hides in the package's revision number. Debian does the opposite and moves to the new upstream release, so on Debian php -v shows the fixed number directly. These are the fixed packages:

ReleasePackageFixed versionphp -v shows
Ubuntu 26.04 LTSphp8.58.5.4-0ubuntu1.58.5.4
Ubuntu 24.04 LTSphp8.38.3.6-0ubuntu0.24.04.138.3.6
Ubuntu 22.04 LTSphp8.18.1.2-1ubuntu2.288.1.2
Ubuntu 20.04 (Ubuntu Pro)php7.47.4.3-4ubuntu2.29+esm57.4.3
Debian 13 (trixie)php8.48.4.27-1~deb13u1 (DSA-6574-1)8.4.27
Debian 12 (bookworm)php8.28.2.35-1~deb12u1 (DLA-4848-1)8.2.35

Notice the Ubuntu 22.04 row: Ubuntu patched its PHP 8.1, although the PHP project itself gives 8.1 no fix. Ubuntu 20.04 and older releases get the fix only through Ubuntu Pro's extended security maintenance. To see the package version that matters on Ubuntu or Debian, ask the package manager instead of PHP:

dpkg-query -W 'php*-common'
sudo apt update && sudo apt install --only-upgrade 'php8*'
sudo systemctl restart php8.3-fpm apache2     # use your version; nginx instead of apache2 if you run it

If you installed PHP from a third-party repository instead, such as the widely used one maintained by OndΕ™ej SurΓ½ (the "Sury" repository on Debian, or its PPA on Ubuntu), the packages carry upstream version numbers, so php -v should show 8.4.27, 8.3.36 and so on after apt upgrade. The one-paste check below knows the difference and reads the right number for you.

EC2 on Amazon Linux 2023: why dnf update says "nothing to do", and the command that works

This is the part of PHP2Shell that is unique to AWS, and it catches experienced Linux admins. Amazon Linux 2023 uses deterministic upgrades: every server is locked to the package repository snapshot of the release it was launched from, such as 2023.12.20260930. A plain dnf update only looks inside that snapshot. Fixed packages land in a newer snapshot, so on an older server dnf looks, finds nothing new and says so.

Here is that trap on an Amazon Linux 2023 server built from the September 30 release, with PHP 8.4 installed:

$ cat /etc/system-release
Amazon Linux release 2023.12.20260930 (Amazon Linux)
$ php -v | head -1
PHP 8.4.25 (cli) (built: Aug 25 2026 18:15:03) (NTS gcc x86_64)
$ dnf check-update 'php8.4*'
Last metadata expiration check: 0:01:25 ago on Fri Oct 23 02:28:17 2026.
$ echo $?
0
$ sudo dnf -y update
Dependencies resolved.
Nothing to do.
Complete!

Exit code 0 from dnf check-update means "no updates available", and the full update agrees: nothing to do, on a server running a PHP version that is open to remote code execution. Even asking for the PHP advisory by name came back empty, because the advisory lives in the newer snapshot too. Now the same check pointed at the release that contains the fix:

$ dnf check-update --releasever 2023.12.20261021 'php8.4*'
php8.4-cli.x86_64                 8.4.27-1.amzn2023.0.1              amazonlinux
php8.4-common.x86_64              8.4.27-1.amzn2023.0.1              amazonlinux
php8.4-fpm.x86_64                 8.4.27-1.amzn2023.0.1              amazonlinux

So the fix is the command printed in the Amazon Linux advisories, which carries the release version. Use the line for your PHP version:

PackageAdvisoryFixed packageCommand
php8.5ALAS2023-2026-33048.5.12-1.amzn2023.0.1sudo dnf update php8.5 --releasever 2023.12.20261021
php8.4ALAS2023-2026-33038.4.27-1.amzn2023.0.1sudo dnf update php8.4 --releasever 2023.12.20261021
php8.3ALAS2023-2026-33028.3.36-1.amzn2023.0.1sudo dnf update php8.3 --releasever 2023.12.20261021
php8.2ALAS2023-2026-33018.2.35-1.amzn2023.0.1sudo dnf update php8.2 --releasever 2023.12.20261021
php8.1NoneNo fix plannedMove to php8.2 or newer

To update every PHP package at once, including extensions such as php8.4-mysqlnd and php8.4-opcache, use a wildcard, and then restart whatever runs PHP so the old code leaves memory:

sudo dnf update --releasever 2023.12.20261021 'php8*'
sudo systemctl restart php-fpm
sudo systemctl restart httpd        # or nginx
php -v | head -1

On the same September server, the advisory form of the command did the job:

$ sudo dnf -y update --advisory ALAS2023-2026-3303 --releasever 2023.12.20261021
Upgrading:
 php8.4-cli        x86_64     8.4.27-1.amzn2023.0.1       amazonlinux     3.9 M
 php8.4-common     x86_64     8.4.27-1.amzn2023.0.1       amazonlinux     817 k
 php8.4-fpm        x86_64     8.4.27-1.amzn2023.0.1       amazonlinux     2.0 M
...
Complete!
$ php -v | head -1
PHP 8.4.27 (cli) (built: Oct 19 2026 14:38:59) (NTS gcc x86_64)

On Amazon Linux 2023 the PHP-FPM service is called php-fpm whatever the PHP version, its pool file is /etc/php-fpm.d/www.conf, and Apache is httpd. Restarting matters more than usual here. Updating the package replaces the files on disk, but running PHP-FPM workers keep the old, vulnerable code in memory until they restart, and the stale-state bug lives exactly in those long-running workers. If you would rather move the whole server to the newest release, which also brings every other security fix since your launch date, use sudo dnf upgrade --releasever=latest instead, after a snapshot, because it updates far more than PHP. Afterwards /etc/system-release shows the new release (on October 23, Amazon Linux release 2023.12.20261021), and later plain dnf update runs look inside that newer snapshot. How releases and deterministic upgrades work in general, and how to check which release a server is on, is covered in Amazon Linux 2023 updates and "Nothing to do".

Ethan: "The scary version is the one where you ran the update, saw 'Nothing to do', and went to bed."

Jake: "That would have been me."

For a fresh install of PHP on Amazon Linux 2023, including the package names and the httpd errors you may meet, see Apache and PHP on Amazon Linux 2023. New servers launched from the October 21 release or later already get the fixed versions.

Amazon Linux 2: the built-in PHP gets no fix

Amazon Linux 2 has two kinds of PHP, and they are in very different situations:

  • PHP 8.2 from Amazon Linux Extras (installed after sudo amazon-linux-extras enable php8.2) is fixed: advisory ALAS2PHP8.2-2026-015, package php-8.2.35-1.amzn2.0.1. Update with sudo yum update php and restart PHP-FPM or Apache.
  • The core php package that yum install php gives you without Extras is listed as No Fix Planned. It is an ancient PHP 5.4 line, far past its end of life.

The difference is easy to see on a fresh Amazon Linux 2 server:

$ sudo yum -y install php-cli && php -v | head -1
PHP 5.4.16 (cli) (built: May 19 2026 21:02:18)

$ sudo yum -y remove php-cli php-common
$ sudo amazon-linux-extras enable php8.2
$ sudo yum clean metadata && sudo yum -y install php-cli && php -v | head -1
PHP 8.2.35 (cli) (built: Oct 21 2026 16:01:03) (NTS)

A recent build date on the PHP 5.4 package can make it look maintained. It is not covered for PHP2Shell, and PHP 5.4 is affected. If php -v on an Amazon Linux 2 server prints a 5.4 version, that server needs the Extras PHP 8.2 at the very least.

Amazon Linux 2 itself reached the end of standard support on June 30, 2026, so this is the moment to plan the move to Amazon Linux 2023 rather than another patch. If you are stuck on Amazon Linux 2 for now, moving PHP to the 8.2 Extras topic and patching it is the stopgap. For what else retired this year, see AWS services and versions retired in 2026.

Lightsail WordPress, LAMP and Nginx (Lightsail-packaged blueprints)

Lightsail has two families of PHP blueprints, and the fix is completely different for each, so first find out which one you have. If the folder /opt/bitnami exists, you have a Bitnami instance and the next section is yours. If not, and you created the instance from Lightsail's own WordPress, WordPress Multisite, LAMP or Nginx blueprint, PHP comes from the operating system's package repositories and updates the normal way:

  1. Take a snapshot first. In the Lightsail console, open the instance, choose Snapshots, then Create snapshot. If anything breaks, you can create a new instance from it in minutes.
  2. Connect with SSH (the browser button works).
  3. Update the packages: sudo apt update, then sudo apt upgrade.
  4. Restart the web server so it loads the new PHP: sudo systemctl restart apache2 for WordPress, WordPress Multisite and LAMP; sudo systemctl restart php8.2-fpm on the Nginx blueprint (use your PHP version in the name).
  5. Confirm: php -v should show the fixed version for your PHP line or newer, and the test file from the version check should show the same for the web server.

Instances created from the Node.js or Ruby on Rails blueprints, or from plain operating-system blueprints such as Ubuntu and Amazon Linux, have no PHP unless you installed it yourself. Windows Server blueprints have none either; if you added PHP to one, replace it with the fixed build from the PHP for Windows downloads page (keep your php.ini) and restart IIS or Apache. If you are deciding whether Lightsail is still the right home for the site, Lightsail vs EC2 prices the same server both ways.

Bitnami blueprints: why apt upgrade does not fix this one

Most older Lightsail WordPress sites, Jake's included, were created from the blueprints packaged by Bitnami. These carry their own copy of PHP in /opt/bitnami/php, separate from the operating system's packages, so apt upgrade finishes cleanly and changes nothing that matters. Check with:

/opt/bitnami/php/bin/php -v

AWS cannot update these running instances, so you have two ways forward, and the first is the better long-term choice.

Option 1, recommended: move to a Lightsail-packaged blueprint. Create a snapshot of the old instance, create a new instance from Lightsail's own WordPress or LAMP blueprint, move your site files and database across, move the static IP to the new instance, check the site, and delete the old instance when you are sure. The new instance updates PHP with apt upgrade, now and for every future security release. It is the bigger job today and the smaller one forever after.

Option 2: point the Bitnami web server at a package-managed PHP. If you cannot move today, the Lightsail guide shows how to install PHP-FPM from the Sury PHP repository (a widely used third-party Debian repository, not run by AWS) alongside the Bitnami copy, and switch the Bitnami Apache or Nginx over to it. In outline, after a snapshot:

  1. Note your PHP line (for example 8.2) from /opt/bitnami/php/bin/php -v, add the Sury repository, and install the matching php8.2-fpm and extensions with apt install --no-install-recommends (that option stops apt from installing a second Apache next to Bitnami's).
  2. Point the new PHP at Bitnami's database socket, usually /opt/bitnami/mariadb/tmp/mysql.sock (older instances use /opt/bitnami/mysql/tmp/mysql.sock), by setting pdo_mysql.default_socket and mysqli.default_socket in the new php.ini.
  3. Create a PHP-FPM pool that runs as the Bitnami user daemon and listens on a new socket, /opt/bitnami/php/var/run/ww2.sock, then enable and restart the new PHP-FPM service.
  4. Replace www.sock with ww2.sock in the Bitnami Apache or Nginx configuration (keep .bak copies) and restart with sudo /opt/bitnami/ctlscript.sh restart apache (or nginx).
  5. Check with the test file: it should print the fixed version, fpm-fcgi, and a php.ini path under /etc/php/. If the path is still /opt/bitnami/php/etc/php.ini, the site is still on the old PHP.

The exact commands are long and specific to each application (WordPress, Drupal, Joomla, Magento and PrestaShop use different folders), so copy them from the Lightsail user guide page "Update PHP on Lightsail instances to address CVE-2026-109618 and CVE-2026-109619" rather than retyping them. The same Sury repository also publishes fixes for PHP 5.6 to 8.1 on Debian, which is the one route to a patched old PHP on Lightsail while you plan an upgrade.

Ethan chose Option 1 for Jake's shop: a new Lightsail WordPress instance, the site exported and imported, the static IP moved across, two hours on a Sunday. "Next time PHP has a bad day," he told Jake, "this is one command."

Elastic Beanstalk: platform version 4.13.13

On Elastic Beanstalk, AWS builds PHP into the platform, so the fix is a platform update, not a package command. The fixed versions are all named 4.13.13 on Amazon Linux 2023:

Platform (solution stack name)PHPReleased
64bit Amazon Linux 2023 v4.13.13 running PHP 8.58.5.12October 21, 2026
64bit Amazon Linux 2023 v4.13.13 running PHP 8.48.4.27October 21, 2026
64bit Amazon Linux 2023 v4.13.13 running PHP 8.38.3.36October 22, 2026
64bit Amazon Linux 2023 v4.13.13 running PHP 8.28.2.35October 22, 2026

If managed platform updates are turned on for the environment, Beanstalk applies the new version in your next weekly maintenance window. Given how fast exploitation started, waiting for the window is a gamble; you can apply it now. In the console, open the environment and use the platform version option on its overview page to move to 4.13.13. From the command line:

# what the environment runs now
aws elasticbeanstalk describe-environments --environment-names my-env \
  --query "Environments[0].SolutionStackName"

# move it to the fixed platform (use your PHP version)
aws elasticbeanstalk update-environment --environment-name my-env \
  --solution-stack-name "64bit Amazon Linux 2023 v4.13.13 running PHP 8.4"

With the EB CLI, eb upgrade in the project folder does the same. Beanstalk replaces or updates the instances, so expect the same brief disruption as any deployment unless the environment uses rolling or immutable updates. If an update leaves you with a 502 error afterwards, the 502 Bad Gateway fix covers the usual causes.

One detail worth knowing: an earlier platform release on October 21 switched off session.upload_progress.enabled (and fatal_error_backtraces on PHP 8.5) as an emergency measure, and 4.13.13 restores PHP's default values now that the real fix is in. The PHP advisory suggests keeping session upload progress off even after patching if you do not use it, so if your application has no upload progress bars, you can set it off yourself with an .ebextensions or .platform configuration file. Environments on retired platform branches, such as PHP 8.1 or Amazon Linux 2 platforms, get no new version: move them to a supported branch.

Containers on ECS, EKS and App Runner: rebuild, do not just restart

A container image freezes the PHP it was built with. Restarting a task or pod starts the same old PHP again, so the fix is always rebuild, push, redeploy. The official Docker php images were updated on October 22: tags such as php:8.4.27-fpm, php:8.4.27-apache, php:8.4.27-fpm-alpine and php:8.2.35-fpm-alpine now exist, and the moving tags (php:8.4-fpm, php:8-apache and so on) point at the fixed builds.

  1. Find the base image. Look at the FROM line in your Dockerfile. If it pins an exact version such as php:8.4.25-fpm, change it to php:8.4.27-fpm or newer. If it uses a moving tag such as php:8.4-fpm, leave it, but force a fresh download in the next step.
  2. Rebuild with a fresh base: docker build --pull -t my-app:php2shell . The --pull option makes Docker fetch the newest base image instead of reusing the old one in its cache, which is the most common reason a "rebuilt" image still has the old PHP.
  3. Check the PHP inside the image before you push: docker run --rm my-app:php2shell php -v
  4. Push to ECR and update the image in your task definition, Kubernetes deployment or App Runner service.
  5. Redeploy. On ECS, register the new task definition revision and update the service, or, if you reuse a tag such as latest, run aws ecs update-service --cluster my-cluster --service my-svc --force-new-deployment so the tasks pull the new image. On EKS, kubectl set image or a new manifest; a reused tag needs imagePullPolicy: Always and kubectl rollout restart.

If you install PHP from Alpine or Debian packages inside your own image instead of using the official php images, the same rule applies: rebuild after your distribution publishes its fixed package. ECR image scanning can then list which images in your registries still carry vulnerable PHP packages; basic vs enhanced scanning explains which scan sees what. If a forced deployment seems to do nothing, ECS force new deployment covers why tasks keep the old image.

Lambda with Bref: two commands

Lambda has no built-in PHP, so PHP on Lambda almost always means Bref, an open-source project that publishes PHP layers and Docker images. Bref published fixed builds 31 minutes after the PHP release, in every Region, for x86 and ARM. Updating is two commands in your project folder:

composer update bref/bref -W
serverless deploy

The -W lets Composer update Bref's own dependencies too; without it, the update can fail. Use your usual deploy command if you deploy with something other than the Serverless Framework. Then confirm which layer each function uses:

aws lambda get-function-configuration --function-name my-function --query Layers
PHPBref 3 layer (bref/bref 3.0.14)Bref 2 layer (bref/bref 2.4.22)
8.5php-85:21Not available
8.4php-84:24php-84:43 and php-84-fpm:43
8.3php-83:24php-83:71 and php-83-fpm:71
8.2php-82:26php-82:115 and php-82-fpm:115

Layer numbers at or above these carry the fixed PHP. If you deploy Bref as a container image, rebuild with docker build --pull on the updated bref/php-84 (or your version) image, whose 3, 3.0.10 and latest tags point at the new builds. Bref 1 is no longer maintained and was not rebuilt, so a Bref 1 function needs the upgrade to Bref 2 or 3 now.

Which functions matter most? Web applications on the PHP-FPM runtime (Laravel or Symfony sites, BREF_RUNTIME=fpm) are squarely in scope; update those first. Event-driven functions, console commands, queue workers and Laravel Octane run the command-line PHP in a single process and are outside the described attack paths, but every layer was rebuilt, so one composer update covers them all anyway. If you built your own PHP custom runtime on provided.al2023, rebuild it with a fixed PHP and redeploy every function that uses it.

AWS WAF rules to use while you patch

If a server cannot be patched this hour, AWS WAF in front of it (on CloudFront, an Application Load Balancer or API Gateway) can narrow the attack surface. It cannot close it: AWS WAF cannot see inside PHP's memory, and one of the two bugs can be triggered in ways a firewall cannot reliably spot. Treat these rules as a seatbelt for the patch window, not a replacement for the patch. If you are new to web ACLs, what AWS WAF is and costs covers the setup.

1. The PHP application managed rule group, version 2.3. AWSManagedRulesPHPRuleSet version 2.3 adds a rule named PHP2Shell_BODY for CVE-2026-109619, and AWS made 2.3 the default version. If your web ACL already uses this rule group at the default version, the rule is already blocking. If you pinned a version, change it to Version_2.3. If you do not use the rule group yet, add it (it costs 100 web ACL capacity units). To check what you have:

aws wafv2 list-available-managed-rule-group-versions \
  --vendor-name AWS --name AWSManagedRulesPHPRuleSet --scope REGIONAL

aws wafv2 get-web-acl --name my-web-acl --id WEB-ACL-ID --scope REGIONAL \
  --query "WebACL.Rules[?Statement.ManagedRuleGroupStatement.Name=='AWSManagedRulesPHPRuleSet']"

For a web ACL on CloudFront, use --scope CLOUDFRONT in the US East (N. Virginia) Region. A rule group entry with no Version field uses the default version. The rule only inspects the request body up to the web ACL's inspection limit: a fixed 8 KB on an Application Load Balancer, 16 KB by default (up to 64 KB) on CloudFront and API Gateway.

2. A body-size cap for CVE-2026-109618. The PHP rule group does not target the out-of-memory bug. For that one, the size rule SizeRestrictions_BODY in the Core rule set (AWSManagedRulesCommonRuleSet) blocks bodies over 8 KB, or you can write the same thing as a custom rule:

{
  "Name": "Block-Oversize-Body",
  "Priority": 2,
  "Action": { "Count": {} },
  "Statement": {
    "SizeConstraintStatement": {
      "FieldToMatch": { "Body": { "OversizeHandling": "MATCH" } },
      "ComparisonOperator": "GT",
      "Size": 8192,
      "TextTransformations": [ { "Priority": 0, "Type": "NONE" } ]
    }
  },
  "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "PHP2ShellBlockOversizeBody" }
}

An 8 KB cap breaks normal file uploads, so it suits sites that do not accept uploads. Even then it is partial: an attack can use many tiny part headers that cost PHP far more memory than their size on the wire.

3. Block uploads entirely, if your site has none. Both bugs enter through multipart/form-data requests. A brochure site, a blog without front-end uploads or an API that only takes JSON can block that content type at the edge:

{
  "Name": "Block-Multipart-FormData",
  "Priority": 1,
  "Action": { "Count": {} },
  "Statement": {
    "ByteMatchStatement": {
      "FieldToMatch": { "SingleHeader": { "Name": "content-type" } },
      "PositionalConstraint": "CONTAINS",
      "SearchString": "multipart/form-data",
      "TextTransformations": [ { "Priority": 0, "Type": "LOWERCASE" } ]
    }
  },
  "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "PHP2ShellBlockMultipart" }
}

WordPress admins: the media library, theme and plugin uploads use multipart requests, so this rule blocks your own uploads too. Scope it so it skips /wp-admin/ from your office address, or accept a few days without uploads.

4. A rate limit on POST requests. A rate-based rule that limits each IP address to about 100 POST requests per 60 seconds makes the repeated attempts these exploits need slower and noisier. It does not stop a single lucky request.

All the examples start in Count mode on purpose. Turn on WAF logging, watch the rule metrics and sampled requests for an hour to confirm they do not match your normal traffic, then change the action to Block. "Measure that review period in hours, not days" is the advice from the AWS Security Blog's PHP2Shell guide, which also has a custom rule for the session-upload-progress trigger (a POST that carries both a PHPSESSID and the PHP_SESSION_UPLOAD_PROGRESS field). For blocking whole countries while you work, see WAF geo blocking; for firewalling at the network level instead, Network Firewall vs WAF.

If you cannot patch today: the php.ini stopgaps

The PHP advisory is blunt that "there are no complete mitigations, updating is the only safe choice." If an update is genuinely impossible for a few hours, these settings remove the demonstrated attack paths. Each one has a cost, so read the notes:

SettingWhat it blocksThe catch
session.upload_progress.enabled=0The confirmed session-upload-progress route to CVE-2026-109619Breaks upload progress bars, which very few sites use. Worth keeping off after patching too.
fatal_error_backtraces=0 (PHP 8.5 only)The confirmed PHP 8.5 route to CVE-2026-109619Fatal errors log without a backtrace
memory_limit=-1, set where applications cannot override itThe predictable out-of-memory point CVE-2026-109618 needsA runaway script can now use all memory; limit memory with the container or cgroup instead
A low post_max_size (8M without uploads, 32M with)Reduces oversized request bodiesDoes not stop small, header-heavy attacks
pm.max_requests = 1 in the PHP-FPM poolRecycles each worker after one request, so stale state cannot reach a second requestSlower, more CPU per request

Two warnings from the advisory are easy to get wrong. Do not limit memory with RLIMIT_AS or RLIMIT_DATA (for example ulimit -v), because those make allocations fail in exactly the way the first bug needs. And after any change, restart every PHP worker; settings only apply to new workers. On Amazon Linux 2023 the main file is /etc/php.ini with extra files in /etc/php.d/; on Ubuntu and Debian it is /etc/php/8.x/fpm/php.ini. Check that no .htaccess php_value line or pool setting puts a finite memory_limit back.

Still on PHP 8.1, 7.4 or older?

Every PHP line older than 8.2 is affected and gets no upstream fix for CVE-2026-109618. The AWS bulletin advises applying the CVE-2026-109619 configuration settings above as an interim measure, restarting the workers and starting the move to a supported PHP immediately. In practice your options are:

  • Upgrade to PHP 8.2 or newer. 8.2 itself reaches end of life on December 31, 2026, so if you are upgrading anyway, 8.4 or 8.5 saves you doing this again in two months.
  • A vendor backport, such as the Sury repository's fixed PHP 5.6 to 8.1 packages for Debian, or a paid long-term-support PHP, to buy time while you test your application on a newer PHP.
  • Take it offline until it is upgraded. For an internet-facing site on an unsupported PHP that cannot be patched, that is what the US government's security agency, CISA, recommends.

Old PHP is often attached to an old operating system, such as Amazon Linux 2 or an old Ubuntu. If your Lambda functions are also on older runtimes, "runtime no longer supported" explains those deadlines.

PHP2Shell detection: were you already attacked? What to check, back to October 17

Patching stops new attacks. It does not undo one that already succeeded, so on any server that was exposed with a vulnerable PHP, spend twenty minutes on these checks. They are the practical indicators of compromise (IOCs) for a web server, whatever exploit was used:

  1. Look for PHP files changed since October 17 in your web root, the classic sign of a planted web shell: sudo find /var/www -name '*.php' -newermt 2026-10-17 -ls. Expect your own updates in the list; look for strange names, files in upload folders, or files that appeared at odd hours.
  2. Look for programs started by the web server account. ps -ef --forest shows each process under its parent. A shell, curl, wget or an unknown binary running under php-fpm or apache is the strongest warning sign there is.
  3. Check the PHP-FPM and web server error logs for clusters of crashed workers, such as child ... exited on signal 11 (SIGSEGV), and bursts of 500 errors after POST requests. Memory-corruption attempts often crash workers before one succeeds.
  4. Check your access logs (or ALB access logs in S3) for bursts of POST requests to pages that never receive form posts, especially with multipart/form-data.
  5. Check outbound traffic. If you use Amazon GuardDuty, review its findings for the instance since October 17; a web server suddenly talking to unusual addresses deserves a look.

Request bodies are not in normal access logs, so you cannot search them for the attack's form fields after the fact. Putting the WAF rules above in front of the site in Count mode is how you start seeing them from now on. If anything looks wrong, treat the server as compromised: snapshot it for investigation, rotate the database password and every key the server could read, and rebuild from a clean image rather than cleaning in place.

Jake: "And if all of that comes back clean?"

Ethan: "Then we got lucky, and we patch faster next time."

Patching many servers at once with Systems Manager

If you run more than a handful of EC2 servers, AWS Systems Manager can check and patch them all from one place, provided they run the SSM Agent with an instance role that allows it. First, an inventory of PHP versions across every server tagged as a web server:

aws ssm send-command --document-name "AWS-RunShellScript" \
  --targets "Key=tag:Role,Values=web" \
  --parameters 'commands=["php -v | head -1"]' \
  --comment "PHP2Shell version check"

Then, for Amazon Linux 2023 servers, the same document can run the fix, release version included, and restart PHP-FPM:

aws ssm send-command --document-name "AWS-RunShellScript" \
  --targets "Key=tag:Role,Values=web" \
  --parameters 'commands=["dnf -y update --releasever 2023.12.20261021 \"php8*\"","systemctl restart php-fpm","php -v | head -1"]' \
  --max-concurrency "25%" --max-errors "1"

--max-concurrency patches a quarter of the servers at a time and --max-errors stops the run after the first failure, so a bad update does not take the whole fleet down at once. Read the output per server in the Systems Manager console under Run Command. Commands run as root, so no sudo is needed. For a gentler start, see what Systems Manager is and what it costs (Run Command itself is free).

The PHP2Shell security patch checklist for AWS

  1. List every place PHP runs: EC2, Lightsail, Beanstalk environments, container images, Lambda functions, and anything bundling PHP inside another product.
  2. Run the one-paste check, or check the version the web server uses, not just php -v. Fixed: 8.5.12, 8.4.27, 8.3.36, 8.2.35 (Ubuntu: package revisions in the table).
  3. Amazon Linux 2023: dnf update --releasever 2023.12.20261021 'php8*'. Amazon Linux 2: Extras php8.2 only; core php has no fix.
  4. Lightsail: apt upgrade on Lightsail blueprints; Bitnami needs a move or a PHP swap.
  5. Beanstalk: platform 4.13.13. Containers: docker build --pull, push, redeploy. Bref: composer update bref/bref -W, deploy.
  6. Restart every PHP worker after every change.
  7. WAF in Count, then Block: PHP rule group 2.3, a body-size rule, multipart block where there are no uploads.
  8. Check for signs of attack back to October 17. Set session.upload_progress.enabled=0 if you do not use it.

Frequently asked questions

What is the PHP2Shell vulnerability?

The name for two critical PHP vulnerabilities, CVE-2026-109618 and CVE-2026-109619, that allow unauthenticated remote code execution on PHP web servers. Both were fixed on October 21, 2026.

Which PHP versions fix CVE-2026-109618 and CVE-2026-109619?

PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. Every earlier release on those lines is affected, and PHP 8.1 and older get no fix.

Is PHP 8.1 affected by PHP2Shell?

Yes, and the PHP project gives it no fix because it is end of life. Some vendors backported one, such as Ubuntu 22.04's php8.1; otherwise upgrade to PHP 8.2 or newer.

Is AWS affected by PHP2Shell?

AWS services themselves are not affected. Any PHP you run on EC2, Lightsail, Elastic Beanstalk, containers or Lambda is your responsibility to update, except Beanstalk with managed platform updates.

How do I update PHP on Amazon Linux 2023?

Run sudo dnf update --releasever 2023.12.20261021 'php8*' and restart php-fpm and your web server. Without the release version, dnf can report nothing to update.

Why does dnf update say "Nothing to do" when PHP is vulnerable?

Amazon Linux 2023 locks each server to its launch release's repository. The fixed PHP is in a newer release, so you must pass --releasever or upgrade to the latest release.

Why does Ubuntu still show PHP 8.3.6 after the security update?

Ubuntu backports fixes without changing the PHP version. On Ubuntu 24.04 the fixed package is 8.3.6-0ubuntu0.24.04.13; check it with dpkg-query -W 'php*-common'.

Is PHP 8.1 on Ubuntu 22.04 fixed?

Yes. Ubuntu patched it in 8.1.2-1ubuntu2.28, although the PHP project gives 8.1 no fix. Run sudo apt update and sudo apt upgrade, then restart PHP-FPM or Apache.

Is PHP on Amazon Linux 2 fixed?

PHP 8.2 from Amazon Linux Extras is fixed (ALAS2PHP8.2-2026-015). The core php package has no fix planned; move to Extras PHP 8.2 or to Amazon Linux 2023.

How do I patch PHP on a Lightsail WordPress instance?

Snapshot it, then sudo apt update and sudo apt upgrade, and restart apache2. Bitnami instances keep their own PHP in /opt/bitnami/php, which apt does not update.

How do I know if my Lightsail WordPress is Bitnami?

If the folder /opt/bitnami exists, it is a Bitnami instance. Check its PHP with /opt/bitnami/php/bin/php -v.

Which Elastic Beanstalk platform version fixes PHP2Shell?

Version 4.13.13 of the Amazon Linux 2023 PHP 8.2, 8.3, 8.4 and 8.5 platforms, released October 21 and 22, 2026.

Does restarting my ECS tasks fix PHP2Shell?

No. The image still contains the old PHP. Rebuild with docker build --pull on a fixed base image, push it and redeploy.

How do I fix PHP2Shell on Lambda with Bref?

Run composer update bref/bref -W and redeploy. Bref 3.0.14 and 2.4.22 use the fixed layers, such as php-84:24 on Bref 3.

Does AWS WAF protect against PHP2Shell?

Partly. The PHP managed rule group version 2.3 targets CVE-2026-109619 and a body-size rule reduces CVE-2026-109618, but only patching PHP fixes the vulnerabilities.

Are PHP command-line scripts affected?

They are not in the described attack paths, because the CLI does not parse web requests. They use the same engine, so update them with the rest.

Is there a workaround if I cannot update PHP?

No complete one. session.upload_progress.enabled=0, fatal_error_backtraces=0 on PHP 8.5 and memory_limit=-1 remove the demonstrated paths. Restart every worker.

Is PHP2Shell being actively exploited?

Yes. Attempts were recorded from October 17, 2026, before disclosure, and broad exploitation attempts followed the release on October 21.

Is PHP2Shell patched?

Yes, in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, released October 21, 2026. Your server is only patched once it runs one of those versions (or your distribution's fixed package) and PHP has been restarted.

How does PHP2Shell work?

A crafted request, typically a file-upload request, either makes PHP run out of memory mid-setup or leaves stale data for the next request in the same worker. Both corrupt memory before your code runs.

PHP2Shell vs Log4j: is it as bad as Log4Shell?

Both are unauthenticated remote code execution in software under countless sites. Log4Shell was easier to exploit; PHP2Shell is rated high complexity, but working exploits appeared within hours.

What is the CVSS score of CVE-2026-109618?

9.2, Critical, under CVSS 4.0. Amazon Linux rates it 8.1, Important, under CVSS 3.1, and NVD's CVSS 3.1 score is 9.8.

For readers preparing for an AWS certification

We have been covering AWS certifications alongside our fixes, so here is a short extra for readers studying for one. If you only came for the fix, you already have it; feel free to skip this part.

Exams that test this topic: Security – Specialty (SCS-C03) • CloudOps Engineer – Associate (SOA-C03) • Solutions Architect – Associate (SAA-C03) • Developer – Associate (DVA-C03 from December 1, 2026).

Here are the exam-style questions this topic tends to raise, with the reasoning you need to answer them:

1. EC2 instances on Amazon Linux 2023 were launched from an older AMI. A fixed PHP package has been released, but sudo dnf update reports Nothing to do. Why?

Amazon Linux 2023 deterministic upgrades lock each instance to the repository of its release; run dnf update with --releasever set to the newer release, or dnf upgrade --releasever=latest.

2. PHP web servers behind an Application Load Balancer must be shielded from a PHP request-body exploit while they are patched, with the least effort. What should be used?

AWS WAF on the ALB with the AWS managed PHP application rule group (AWSManagedRulesPHPRuleSet) at the default version, as a temporary control alongside patching.

3. An AWS WAF rule on a CloudFront distribution must inspect request bodies up to 64 KB. What has to change?

Raise the web ACL body inspection limit to 64 KB in its association configuration; the default is 16 KB, and an ALB is fixed at 8 KB.

4. A company must run the same patch command on 300 tagged EC2 web servers in batches and stop after the first failure. Which feature fits?

Systems Manager Run Command with the AWS-RunShellScript document, tag-based targets, max concurrency and max errors.

5. An Elastic Beanstalk environment should receive new platform patch versions automatically during a weekly window. What should be enabled?

Managed platform updates for the environment.

6. An ECS service runs an image tagged latest. The image was rebuilt on a patched base and pushed to ECR, yet the running tasks still run the old code. What is required?

A new deployment, such as update-service with force-new-deployment or a new task definition revision, so the tasks pull the new image.

Exam codes and dates change often. Our AWS certification changes page keeps track of what is current.

Jake's new Lightsail server got its first PHP security update two weeks later, on a weekday, in the time it took the kettle to boil. "That's it?" he asked. Ethan nodded. The old Bitnami instance, snapshot kept for a month just in case, was the last thing he deleted. "It worked fine for years," Jake said, a little sad. "It did," Ethan said. "It just couldn't be fixed when it mattered."

📌 If you keep one line from this page

Update to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35 with the command your AWS service needs (on Amazon Linux 2023, add --releasever 2023.12.20261021), restart every PHP worker, and check for intrusions back to October 17.

CVE-2026-109618 · CVE-2026-109619 · AWS bulletin 2026-143-AWS · ALAS2023-2026-3301 to 3304 · October 2026.

Revision note. Written October 23, 2026, two days after the PHP security release, with the fixed versions, Amazon Linux advisories, Elastic Beanstalk platforms, Bref layers and AWS WAF rule group as they stood on that date. "A stitch in time saves nine," the proverb says, and with PHP2Shell the stitch is an hour, not a week.

Related