Read this first: scope and limits of this article This article is written for educational and defensive purposes. It does not explain how to carry out an attack and contains no exploit code. The facts are those known on 25 October 2026, four days after the fixes were released, and they may change quickly. Every important claim links to its source; when a source is third-party or unofficial, or when I could not verify a point, I say so.

Why PHP2Shell deserves our attention

On 21 October 2026, the PHP project published a security advisory rated critical: two vulnerabilities, CVE-2026-109618 and CVE-2026-109619, that can let an unauthenticated attacker run code on the server. The pair is known as "PHP2Shell", the name given to the exploit by the Calif researchers, who found the flaws together with OpenAI and Wiz according to their write-up. The PHP project's notes and Debian's tracker point to that name as well.

Rather than talk about a global earthquake, let us stay factual. What is established: the PHP project itself says "all PHP installations serving web requests" are concerned, with the highest risk for Apache mod_php. Red Hat rates the issue important and notes that on default PHP-FPM deployments, code execution remains "difficult in practice". The security firm Sansec reports (third-party source) that mass exploitation now looks less likely than feared, because the public exploits it examined do not work on a default installation, while also relaying early attacks reported by Cloudflare on release day. The risk is therefore real, uneven depending on configuration, and the patch is the only complete answer.

Why is server-side command execution so serious? Because it gives the attacker the rights of the web process: reading the application's files and secrets (database passwords, API keys), modifying the site, then pivoting to other systems on the internal network. What separates a manageable incident from a lasting compromise is how fast you fix and how well privileges are compartmentalised.

Part 1: PHP2Shell for beginners, understanding the problem

What PHP2Shell refers to

It is two memory-handling defects in the PHP engine, not a flaw in one particular application. PHP is not "inherently vulnerable": these bugs sit in the core of the language (the engine that runs your scripts) and they are fixed in identified releases. According to the official advisories:

  • CVE-2026-109618 (GHSA advisory): PHP uses a non-local jump (longjmp()) to bail out when a memory allocation fails. If that happens while the request's internal data is only half initialised, end-of-request cleanup reads an invalid state.
  • CVE-2026-109619 (GHSA advisory): internal state owned by one request can survive after the matching memory has been freed. A later operation in the same process can then use it (a "use after free") before normal initialisation replaces it.

Both carry a CVSS v4.0 score of 9.2 according to the secondary sources I consulted (I did not check the score with the CNA).

How a request normally works

A browser sends an HTTP request. The web server (Apache, nginx...) receives it and hands it to PHP: either by running PHP inside the same process (mod_php, an Apache module) or by passing it to a separate service (PHP-FPM, over FastCGI). Before your code even runs, PHP parses the request body (forms, uploaded files) to fill $_POST and $_FILES. Once the response is built, PHP cleans up the request's memory and the process moves on to the next one. This "start, parse, run, clean up" cycle is what the flaws disrupt.

The mechanism, without the code

The Calif researchers describe the logic in their write-up:

  1. Cause a controlled memory failure. PHP caps memory per request (memory_limit, 128 MB by default). A multipart/form-data request (the format used for file uploads) can, with nested fields or empty parts, make PHP consume far more internal memory than its size on the wire while staying under post_max_size. The official advisory adds bodies without a usable declared length and parts with an unbounded number of headers.
  2. Interrupt PHP at the wrong moment. The allocation failure makes PHP bail out in the middle of an operation, without running the tidy-up that was planned.
  3. Leave an inconsistent state. According to the official advisory, with mod_php the request shutdown phase runs even if startup failed, so it processes that invalid state. All of this happens before application code runs: flawless application code does not protect you.
  4. Exploit the inconsistency. With precise preparation of memory (the heap), the inconsistency can become code execution.

According to the advisory, PHP-FPM fares better: its child process exits when startup fails, which avoids consuming the invalid state. But source analysis still lists PHP-FPM as "susceptible" through other paths, although no complete exploit for that mode has been demonstrated. FrankenPHP is judged likely susceptible like mod_php, and LSAPI like FPM (source analysis, not validated by an exploit).

Who plays which role? The PHP code (your application) is not at fault. The engine (Zend) holds the defect. Extensions can also be involved: the best-documented CVE-2026-109619 path goes through the upload-progress tracking feature of the session extension (session.upload_progress). The web server integration (mod_php or FPM) determines severity. The operating system only matters at the end, as the victim: commands run with the rights of the web process user.

As for command-execution functions such as system() or exec(), nothing in the sources I consulted makes enabling them a condition of the attack: code execution comes from memory corruption, not from misuse of those functions. Disabling them (disable_functions) remains good general practice, but I have no source showing it blocks this attack. Do not rely on it.

ClientWeb serverPHPSystemBooby-trappedmultipart requestBody passed to PHPBody parsing, memory exhaustedEmergency exit, inconsistent stateCommands possible ifexploited
Path of a malicious request: the flaw triggers while PHP parses the body, before application code; command execution is only a possible consequence.

Possible consequences

It depends on privileges and configuration: reading files and secrets accessible to the web user, tampering with the application, planting a backdoor, pivoting to other machines. Calif says it confirmed pre-authentication code execution on several well-known applications (WordPress, Drupal, Joomla, Magento, Nextcloud, Laravel and others, in recent versions): the application is not the flaw, but it does not protect you from it.

Contested or nuanced facts Calif writes that exploitation is "always possible under default configurations"; Sansec reports that the public exploits it tested do not work on a default installation; PHP names mod_php as the demonstrated case. These statements are not contradictory (different paths and preconditions), but be careful: a default configuration is not a protection.

Part 2: how to assess your exposure

1. Identify the PHP version and where it comes from

php -v                      # command-line version
php -i | grep -E "Server API|memory_limit|post_max_size|session.upload_progress.enabled"
rpm -q php-common           # RHEL, AlmaLinux, CentOS (distribution or Remi package)
dpkg -l 'php*' | grep ^ii   # Debian, Ubuntu

Beware: the command line does not necessarily use the same php.ini as the web server. To know what the service really sees, query it in its own context (for example a temporary, protected diagnostic page, removed afterwards) or read the FPM pool and vhost configuration.

Also note the origin: distribution package, third-party repository, Docker image, Windows binaries, local build. It decides where to look for the fix.

2. Identify the execution mode

apachectl -M | grep php (Apache module), systemctl status php*-fpm (FPM), presence of php-cgi, FrankenPHP or LiteSpeed. As seen above, mod_php is the most exposed case according to PHP.

3. Compare with confirmed fixes

BranchStatus per php.netOfficial fixed version
8.5Maintained8.5.12
8.4Maintained8.4.27
8.3Maintained8.3.36
8.2Maintained8.2.35
8.1, 8.0, 7.4End of lifeNo release published; minimal source fix branches (see part 4)
7.3 and olderEnd of lifeNothing official

The GHSA advisories list every version earlier than these four numbers as affected. Calif places the oldest path it found at PHP 5.4.0.

Classic trap: on distribution packages, the version number does not always change. A fixed package can still show 8.1.34 while containing the fix. Check the package changelog (method given by Sansec, third-party source):

# Debian, Ubuntu (adapt the version)
zgrep CVE-2026-109618 /usr/share/doc/php8.2-common/changelog.Debian.gz
# RHEL, AlmaLinux, Rocky
rpm -q --changelog php-common | grep CVE-2026-109618

Even this check has a limit: it proves a maintainer says they handled the CVE, not that the fix is complete or identical to the PHP project's (see part 4).

4. Detection scanner or exploitation proof tool?

A detection scanner looks for clues (advertised version, observable behaviour). An exploitation proof tool proves code can be executed. Do not confuse them, and run neither on a system that is not yours.

I read the code of php2shell-scanner, published by the Assetnote research team (Searchlight), which credits Calif for the discovery. What the code actually does:

  • It sends a control request followed by up to three booby-trapped multipart requests (fields nested 62 levels deep, from 1 to 20 MiB), about 29 MiB in total per tested path.
  • It reports "vulnerable" on a PHP memory error, a differential empty HTTP 500, a PHP-FPM worker failure, or an advertised version known to be unpatched.
  • It does not prove exploitation: it observes behaviour.

Its limits, acknowledged in its own README:

  • False positives: on some configurations (low memory_limit, high max_multipart_body_parts), a patched version returns the same response as a vulnerable one.
  • False negatives: no crash is not a guarantee. A remote scan sees neither internal configuration nor other paths (other scripts, other vhosts).
  • Backported versions: per the code, an advertised version below 8.2 with no official fix is judged vulnerable. A backported package (still advertising 7.4.33) is therefore wrongly classed "vulnerable" if PHP exposes its version.
  • Network impact: it is an active test that can kill a worker or exhaust memory. Reserve it for your own systems, outside peak hours, with internal approval.

Simple rule: a scan is a clue, not a verdict. No result proves nothing; a positive result on a backported version must be checked another way (package changelog, behaviour test in a lab).

Part 3: solutions to fix the problem

For each strategy: when, prerequisites, advantages and limits, post-deployment checks. Checks common to all: restart all workers (FPM, Apache), verify the version actually loaded by the service, rerun application tests, watch the error logs.

PHP 8.2 to 8.5 (maintained branches)

  • When: always, if the application allows it.
  • Prerequisites: package or binary at 8.2.35, 8.3.36, 8.4.27 or 8.5.12 at minimum.
  • Advantages: official, supported fix, no third-party dependency.
  • Limits: changing branch (8.3 to 8.4) is a migration, with its incompatibilities. Moving to PHP 8 fixes nothing by itself: PHP 8.0 and 8.1 are also affected. Only 8.2.35, 8.3.36, 8.4.27 and 8.5.12 (or later) contain the official fix.
  • Checks: php -v on the service side, extension load test, file upload tests.

The official fix replaces the longjmp() jump with a cleaner exit: a "soft" stop at the next safe point of the virtual machine, and an immediate stop if consumption reaches a second, higher threshold (GHSA advisory). It therefore fixes the defect rather than masking it.

PHP 7.x, 8.0 and 8.1 (end-of-life branches)

According to PHP, these branches no longer receive project updates, but the security team published minimal source fixes for 7.4, 8.0 and 8.1: branches PHP-7.4-CVE-2026-109618-109619, PHP-8.0-... and PHP-8.1-.... This is source code, with no archive, binary or version-number change.

For 7.3 and older (5.x, 7.0 to 7.3), I found no official fix. Third parties offer some (see part 4), and their equivalence with the official fix has to be established, not assumed.

  • When: migration impossible in the short term.
  • Prerequisites: either a vendor that backports, or build skills.
  • Limits: availability depends on the component, the maintainer and the distribution channel; no fix is automatic.
  • Checks: see part 4.

Debian

According to the Debian security tracker (consulted on 25 October 2026): Debian 12 bookworm (php8.2) is fixed in 8.2.35-1~deb12u1 (DLA-4848-1); Debian 13 trixie (php8.4) is fixed in 8.4.27-1~deb13u1 (DSA-6574-1). For Debian 11 (php7.4), the only lead I found is Freexian's paid extended support (ELTS), from a web search I did not re-check on the vendor's own page.

  • When: Debian servers using distribution packages.
  • Prerequisites: apt update && apt upgrade, security repository enabled.
  • Advantages: integrated fix, updates can be automated.
  • Limits: PHP versions are frozen by the distribution; support for an old version may be paid or absent. The third-party repository deb.sury.org (Ondřej Surý) offers older versions according to Sansec: evaluate it like any third-party repository (part 4).
  • Checks: apt list --installed 'php*', changelog, restart FPM or Apache.

CentOS and RHEL-compatible systems

Red Hat publishes bulletin RHSB-2026-013 (published 21 October 2026, updated 23 October). It lists RHEL 7, 8, 9 and 10 as concerned. A notable detail: on the PHP shipped with RHEL 7, Red Hat says the vulnerable code for CVE-2026-109618 is not present, and only CVE-2026-109619 applies. That holds only for Red Hat's PHP: a PHP 7.4 from a third-party repository (Remi, for instance) is different software, to be handled according to its own vendor. According to Sansec, Remi offers fixes for 7.4, 8.0 and 8.1.

The point of caution is distribution end of life: CentOS 7 is no longer maintained by the project; RHEL 7 is covered only by paid extended support. Running an old distribution often means depending on a third party for PHP. On AlmaLinux or Rocky, check the errata for your release.

  • Checks: rpm -q --changelog php-common | grep CVE-2026-109618, package version and release, service restarts.

Windows

PHP says the Windows sources and binaries of the fixed releases are on the download page, so for 8.2 to 8.5. I found no official fixed Windows binary for 8.1 and older.

  • General procedure: identify where your current binaries come from (php.net, a WAMP/XAMPP stack, a vendor installer), download the fixed version, check the published signature or hash, stop IIS or Apache, replace the PHP folder keeping a copy of the old one and of php.ini, restart.
  • Limits: all-in-one stacks ship their own PHP, on their own schedule.
  • Checks: php -v and php --ini for the right folder, the service's diagnostic page.

Docker

The official php image is rebuilt for maintained branches (per third-party sources, within hours of the release) and, according to Sansec, no fix is planned for 8.1 and older in the official images.

  • When: containerised applications.
  • Prerequisites: recent tag (php:8.4-fpm at 8.4.27 or later), image rebuild (docker build --pull --no-cache), update of underlying layers, redeployment of all containers, including those that have been running for months.
  • Limits: an "up to date" image that is never redeployed stays vulnerable. A moving tag is convenient but poorly traceable: pin the digest once validated.
  • Checks: docker run --rm <image> php -v, inventory of images in production, search for containers based on old tags.

Part 4: when upgrading is impossible

This part addresses teams maintaining legacy applications (compatibility, certification, cost, dependencies, contracts). The first decision is who produces the fix.

Origin of the fixWhat it isWhat can be verified
Official maintainerRelease published by the PHP project (8.2.35 and later)Release signatures, GHSA advisories
Project source fixPHP-7.4, 8.0, 8.1 "CVE-2026-109618-109619" branches, no version or binaryPublic diff, to be compiled yourself
BackportA third party (distribution, Remi, LTS vendor) adapts the fix to an old versionChangelog, published patch, tests
Package rebuilt by a third partyRebuild from someone else's sources, with or without changesSources, patches, signature, reproducibility
Package built and signed by your organisationInternal pipeline (part 5)Everything, in principle: you carry the cost

Case study: the Rocketsky repository

Let us examine objectively the branches listed on yum.rocketsky.ch. It is a third-party, unofficial source, which I assess without presuming it reliable or dangerous.

What the page states (consulted on 25 October 2026): signed RPM packages for CentOS 7 x86_64, nine branches marked "Available" (5.6.40, 7.1.33, 7.4.33, 8.0.30, 8.1.34, 8.2.35, 8.3.36, 8.4.27, 8.5.12), built on Remi's EL7 packaging, with gpgcheck=1, repo_gpgcheck=1, sslverify=1, a published key fingerprint, source RPMs, "provenance records", a package index with checksums, and a plug-in that prevents switching branch by accident. The KNOWN-LIMITATIONS-7.4 page describes release 20261021.1.el7.rocketsky: the micro version stays 7.4.33, and the adopted fix terminates the process immediately when memory is exhausted (without running shutdown functions) and disables session upload progress. It also documents existing defects (GD, ICU, interactive CLI).

What is verifiable, hence to be verified: the key fingerprint through a channel other than the site itself (the site recommends it), the source RPMs and the fix's diff against the official code, the exact content of each package compared with the one you already use.

What I could not establish:

  • In the pages I consulted I found no identifiable publisher or organisation; the site mentions donation funding (a Ko-fi link). That says nothing about the quality of the work, but it weighs in a business decision (continuity, liability, support).
  • For 5.6 and 7.1, PHP published no source fix: the fix is therefore a third-party adaptation, whose equivalence I cannot confirm.
  • The shared rocketsky-php-common repository supplies runtime dependencies; its list of source RPMs contains system components (for example httpd, glibc). I did not determine whether they can replace installed system packages. Check before enabling that repository, for example by enabling only the repository of the wanted branch with --disablerepo='*' --enablerepo=... and inspecting the transaction.
  • No assessment of the security of the rest of the build chain (build machine, key protection).

My assessment: neither an endorsement nor a warning. A third-party repository can be a reasonable bridge, provided you treat it as a critical dependency: verify, test, plan the exit.

Checks before using a third-party repository

  1. Maintainer identity and reputation: who, what structure, since when, what track record of published advisories.
  2. Traceability of sources and patches: identified upstream sources, patches published and reviewable.
  3. Match with the expected fix: compare the diff with the official fix for the source branch (for example the PHP-7.4/8.0/8.1 branches); if the fix is a variant (such as an immediate stop instead of a soft stop), understand the behavioural differences.
  4. Reproducibility: can you rebuild the RPM from the source RPM and get a comparable result?
  5. Signature and key management: fingerprint verified out of band, gpgcheck and repo_gpgcheck enabled, a plan for key rotation or compromise.
  6. Compatibility: ABI (binary interface), extensions (PECL, in-house), system libraries, existing configuration.
  7. Regression tests and rollback: a staging environment identical to production, the previous package kept, a tested rollback procedure.

A version number proves nothing

A "fixed" package can keep the same number (7.4.33): only the package release changes. Conversely, an identical number can hide an unpatched package. Validate technically: changelog mentioning the CVE, comparison with the reference fix, and a behaviour test in a lab. Beware: the test must match the fix. An immediate process kill and the official fix's "soft" stop do not behave the same way, and a test valid for one may not be valid for the other.

Part 5: building your own secure package repository

For software vendors, public administrations and institutions that must control the provenance of their packages, an internal repository is not a luxury. Let us separate three things that are often confused:

  • A mirror copies a third party's packages, changing nothing. It improves availability, not trust.
  • A repository that redistributes third-party packages republishes them after an integrity check. You gain control over access and timing, but the content remains the third party's.
  • An internal rebuild-and-validate pipeline starts from verified sources, applies reviewed patches, compiles, tests and signs with your key. It is the only option that gives you end-to-end control.
1Verified sourceofficial archive2Integritysignature, hash3Traced patchreviewed diff4Controlled buildisolatedenvironment5Testsfunctional,security6Signingprotected internalkey7Internalrepositoryauthenticatedaccess8Deploymentgradual, rollback
A controlled supply chain: each step produces evidence (hash, diff, build log, test results) that makes the final package explainable and reproducible.
  1. Fetch an identified source. Official archive or public project branch, exact version recorded.
  2. Verify integrity and origin. Release signature, hash compared through a second channel.
  3. Apply a traceable patch. The official fix where it exists (for 7.4, 8.0 and 8.1, the PHP project's branches), reviewed and versioned.
  4. Build in a controlled environment. Clean build machine or container, pinned dependencies, log kept.
  5. Test. Functional (your applications), security (behaviour against booby-trapped requests, in a lab), regression (uploads, extensions).
  6. Sign the packages. Dedicated key, stored safely (hardware module or vault), with a rotation procedure.
  7. Publish to an authenticated repository. Restricted access, signed metadata.
  8. Deploy gradually. A few machines first, monitoring, previous version ready.

This approach is a risk-management strategy, not a guarantee. It has a real cost: someone must follow the security advisories of PHP and of linked libraries (OpenSSL, libxml2, GD...), rebuild regularly, renew builds, maintain the skills. A branch abandoned by its maintainers becomes your responsibility: every new flaw will have to be ported by you. Once the old branch is frozen, the real goal remains to leave it.

Part 6: adding a complementary defence with ModSecurity

A web application firewall (WAF) inspects HTTP requests before they reach the application. ModSecurity is an open-source filtering engine; it installs as an Apache module, or in front of nginx through a connector. It applies rules, often grouped in a set such as the OWASP Core Rule Set (CRS), which detects generic attack families (SQL injection, XSS...).

1RequestHTTPbrowser, bot2WAFModSecurityinspects, logs, blocks3Web serverApache, nginxreceives if allowed4PHPFPM or mod_phpto be fixed
The WAF sits in front of the web server: it inspects, logs and, once tuned, blocks. It reduces exposure but does not fix PHP.

Detection, blocking and fixing are three different things. Detecting raises a signal; blocking stops the request from getting through; fixing removes the defect. Only updating PHP fixes.

For PHP2Shell, the official sources recommend also acting at the front end: bound the decoded request size (including without Content-Length), the number of fields, multipart parts, headers and the nesting depth, or block multipart if the application does not need it (GHSA advisory). Community rules also exist (for example this repository or this analysis): these are third-party sources I did not audit, and I found no official OWASP CRS rule set dedicated to these CVEs.

Limits of a WAF: a WAF parses the multipart body in its own way and can diverge from PHP (parsing differences, encodings, fragmented requests); attack variants bypass narrow signatures; strict rules cause false positives (for example legitimate forms with nested fields); and any path that bypasses the WAF (direct access to the origin server, another port, an internal service) stays exposed.

An example to test in a controlled environment

The directives and variables below exist in the ModSecurity v2 reference manual (ARGS_NAMES, FILES_NAMES, operators @streq, @rx). I did not run these rules: the syntax follows the documentation, but their behaviour on your stack remains to be validated. They are not exhaustive protection.

# Observation only: nothing is blocked
SecRuleEngine DetectionOnly
SecRequestBodyAccess On
SecAuditEngine RelevantOnly

# Session upload progress tracking field (see CVE-2026-109619)
SecRule ARGS_NAMES "@streq PHP_SESSION_UPLOAD_PROGRESS" \
  "id:9900001,phase:2,pass,log,auditlog,msg:'Session upload progress field'"

# Field names nested three levels or more (may hit legitimate forms)
SecRule FILES_NAMES|ARGS_NAMES "@rx \[[^\]]*\]\[[^\]]*\]\[[^\]]*\]" \
  "id:9900002,phase:2,pass,log,auditlog,msg:'Deeply nested field name'"

The identifiers 9900001 and 9900002 are arbitrary: adapt them to your local range.

Operational approach

  1. Inventory the entry points: every reachable PHP script, vhosts, ports, direct paths to the origin server, internal access.
  2. Enable and configure: rule engine, request body access, size limits, audit log.
  3. Observe in detection mode (DetectionOnly) over a representative period.
  4. Analyse the logs: which legitimate requests are flagged, where the others come from.
  5. Tune: targeted exclusions, thresholds, CRS paranoia level.
  6. Switch to blocking once false positives are handled, first on a limited scope.
  7. Test for regressions: forms, uploads, APIs.
  8. Monitor continuously: alerts, periodic rule review. A WAF that is never reviewed becomes a false sense of security.

The WAF complements remediation; it does not replace it.

Part 7: prioritised action plan

Within 24 hours

  • Inventory the Internet-facing PHP servers, their mode (mod_php, FPM), origin and actual version.
  • Apply the temporary and partial measures from the official advisory, understanding their effects: memory_limit=-1 enforced so applications cannot change it (for example php_admin_value in the FPM pool), a low post_max_size (8M, or 32M if file uploads are required), session.upload_progress.enabled=0 in php.ini or the pool configuration (not through ini_set() or .user.ini), restart of all workers. memory_limit=-1 removes the memory cap and raises the risk of exhaustion: plan a container or cgroup limit, but not RLIMIT_AS or RLIMIT_DATA, which the advisory advises against because they can cause the very allocation failure at stake. On PHP 8.5, fatal_error_backtraces=0 blocks the known fatal-backtrace path.
  • Apply front-end limits (decoded size, number of parts).

Within the week

  • Update to a confirmed fix: 8.2.35, 8.3.36, 8.4.27, 8.5.12, or a fixed distribution package.
  • For old branches: choose between an LTS vendor, an evaluated third-party repository (part 4), or an internal rebuild (part 5).
  • Put compensating controls in place: WAF in detection, then blocking.
  • Look for signs of compromise: unexpected recent PHP files, abnormal child processes of the web service, suspicious multipart requests in the logs.

Within the month

  • Validate (regression tests), monitor, document the rollback procedure.
  • Decide on an internal repository and who maintains it.
  • Plan modernisation: an exit date for each end-of-life branch.

A third item to follow: on 23 October, PHP published an informational advisory about a third flaw, CVE-2026-115560, tied to the same session upload progress feature; according to Red Hat, disabling that feature fully neutralises it. I did not analyse that advisory in detail.

Summary of options

OptionRelevanceConstraintsLimits
Fixed PHP 8.2 to 8.5General caseApplication compatibility, migrationA recent branch number is not enough, you need the right version
Fixed distribution packageDebian, RHEL and derivatives still supportedDistribution cycleFrozen version, check the package changelog
Paid LTS vendorEnd-of-life branches, need for supportCost, contractual dependencyQuality and delays specific to each vendor
Evaluated third-party repository (e.g. Rocketsky)Temporary bridge on CentOS 7Verification of key, patches, ABIMaintainer identity not established, unofficial origin of the fix for 5.6 and 7.1
Build from project branches7.4, 8.0, 8.1 with in-house skillsPipeline, testsResponsibility for every future fix
Internal repository and pipelineVendors, administrationsMaintenance cost, key managementNot a guarantee; continuous renewal
PHP settings and front-end limitsEmergencySide effects (memory, file uploads)Partial: does not remove the defect
WAF (ModSecurity)Defence in depthTuning, false positivesBypassable, does not replace the fix

Sources and references

Primary sources (PHP project and vendors):

Third-party or unofficial sources:

Points I did not verify: the CVSS score (taken from secondary sources), Debian 11 support status (ELTS), the Remi and Sury fixes (cited by Sansec), the state of official Docker images for 8.1 and earlier (Sansec), the equivalence of third-party fixes with the project's, and any development after 25 October 2026.