Situation reviewed on 21 October 2026, after the patches were released. Facts about the vulnerabilities come from the official sources linked in each section. The operational guidance is ekko’s proposed response and should be adapted to each server; no attack testing or audit of third-party hosting has been carried out.
What should be done immediately on a website running PHP?
Identify the interpreter behind each domain, install a fixed release and restart its processes. Until patching is possible, access should be blocked at the web server or proxy so that requests never reach PHP.
- Open an incident with the hosting provider or server administrator. It should cite both identifiers, CVE-2026-109618 and CVE-2026-109619, and ask for confirmation of the installed package and of the process restart.
- Take an inventory of every domain. Subdomains, staging environments, shops, webmail, file managers and long-forgotten applications may each run a different version.
- Make sure a restorable backup exists of data and configuration, stored off the server. For an online shop, the maintenance window is best chosen so that no orders are lost.
- Apply the patch matching the branch and provider, test the critical functions and restart the processes running PHP. Should that not be feasible today, the urgent measures from the official advisory can be used in the meantime.
- Check the result from the website itself and keep evidence for each domain. Console output alone is not enough.
The procedure varies with the environment, whether managed hosting, a VPS or a container platform, and each case is covered separately below.
What are CVE-2026-109618 and CVE-2026-109619?
Two critical PHP vulnerabilities, published on 21 October 2026, that allow code execution on the server without authentication. This is their fact sheet.
| Detail | CVE-2026-109618 | CVE-2026-109619 |
|---|---|---|
| GitHub advisory | GHSA-w8hw-w9fx-j79w | GHSA-6wmf-4rv5-p3rp |
| Official name | RCE via OOM corruption | RCE via stale global state |
| Root cause | Memory corruption when memory_limit is exhausted |
Stale global state across requests (use-after-free) |
| Impact | Unauthenticated remote code execution | Unauthenticated remote code execution and memory disclosure |
| Severity | CVSS v4.0 9.2, critical | CVSS v4.0 9.2, critical |
| Exploitation validated on | Apache with mod_php |
mod_php and PHP-FPM |
| Vulnerable versions | Any release below 8.2.35, 8.3.36, 8.4.27 or 8.5.12 within its branch | Same |
| Fixed in | 8.5.12, 8.4.27, 8.3.36 and 8.2.35 | Same |
| Official partial measure | Enforced memory_limit=-1, low post_max_size and request limits |
session.upload_progress.enabled=0 and, on 8.5, fatal_error_backtraces=0 |
Both share the vector CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N, meaning they can be exploited over the network without credentials or user interaction, albeit with high complexity. They also share the same weaknesses (CWE): CWE-416, CWE-755, CWE-824, CWE-1325 and CWE-1419. The information comes from the php.net security advisory and the two GitHub advisories listed in the table.
What happened, and which releases fix the problem?
PHP has released fixes for two remote code execution flaws. The interpreter patch is essential even when the CMS and its extensions are fully up to date.
The PHP security team issued an advance notice on 20 October, rating both flaws CVSS v4.0 9.2 and scheduling the release for 21 October at 14:00 UTC (16:00 in Madrid). That time was a forecast, and it did not guarantee that every hosting provider would have the patch available at that moment.
The security advisory of 21 October confirmed the fixed releases and the possibility of unauthenticated remote code execution. The official changelog links both fixes:
| Branch | First fixed release for this incident |
|---|---|
| 8.5 | 8.5.12 |
| 8.4 | 8.4.27 |
| 8.3 | 8.3.36 |
| 8.2 | 8.2.35 |
These are the minimums for this incident rather than a permanent recommendation. Anyone reading this guide later should check the latest security release available for their branch.
According to PHP, Linux distributions and long-term support (LTS) vendors received the patches in advance. If a provider still offers no fixed package, it is reasonable to ask why. One date is also worth noting: PHP 8.2 stops receiving security fixes on 31 December 2026, so anyone patching an 8.2 installation today would do well to plan the branch upgrade now.
For PHP 8.1 and older, the project no longer publishes regular releases. The options are a verified vendor backport or a move to a supported branch. PHP has made minimal source patches available for 7.4, 8.0 and 8.1, intended for those who build the interpreter themselves or have no LTS vendor. This neither restores support nor means the hosting will update itself. Details are in the official advisory.
With distributions, what matters is the complete package revision. Ubuntu 24.04, for example, ships the fix as 8.3.6-0ubuntu0.24.04.13, and Ubuntu 22.04 as 8.1.2-1ubuntu2.28. The base number looks older than the upstream minimum because the package carries backported patches. Both CVEs appear in bulletin USN-8948-1. These figures apply only to Ubuntu’s official repositories, not to a PPA, another distribution or a control panel’s packages.
How do these two vulnerabilities work?
Both concern how PHP manages memory between requests. In one case data is left half-initialised; in the other, a request reuses references that have already been freed.
CVE-2026-109618 (GHSA-w8hw-w9fx-j79w): RCE via OOM corruption
When memory runs out, PHP leaves the current operation through a longjmp() jump. If that happens in the middle of an initialisation, the subsequent cleanup works on invalid state. Researchers achieved full remote code execution over HTTP against mod_php, using PHP’s default memory and input limits, before any application code had run. The mechanism is described in the PHP technical advisory.
The advisory also explains how a request can exhaust memory while apparently staying within PHP’s limits, and much of the urgent guidance follows from this:
- A multipart request lacking a usable
Content-Lengthcan get past thepost_max_sizecheck and keep sending data. - Each part of a multipart submission accepts an unlimited number of headers, which take up far more memory inside PHP than on the wire.
- Empty file fields do not count towards
max_file_uploads, yet still generate their internal structures, and nested field names multiply that work.
The fix replaces longjmp() with a deferred out-of-memory condition, handled at the next safe point, and an immediate termination once consumption reaches a second, higher threshold.
CVE-2026-109619 (GHSA-6wmf-4rv5-p3rp): RCE via stale global state
Here, a PHP process keeps references to memory from a request that has already been freed, and another request handled by the same process uses them before they are reinitialised. This is what is known as a use-after-free.
A successful attack needs two pieces. The first, which the advisory calls the “producer”, is an interruption that leaves state uncleared: a fatal error, an out-of-memory condition or an exceeded execution time. The second, the “consumer”, is an operation that reads that state before normal initialisation. Two consumers are confirmed: an INI configuration warning applied on each request, and session upload progress. The two proven cases are PHP 8.5 fatal error backtraces, with exploitation demonstrated against mod_php, and the session lifecycle, validated against both mod_php and PHP-FPM; the latter also requires a suitable operation in the application. Details are in the second technical advisory.
Confirmed impact
Exploiting either flaw yields code execution with the privileges of the web server account, without authentication; the second also allows memory to be read. In practice, everything that account can read is exposed, from wp-config.php to database credentials.
The CVSS score reflects high attack complexity. Running many processes alongside legitimate traffic lowers the chance of success per attempt but, according to PHP, does not remove the condition.
This matters for diagnosis. An application that validates its forms properly says nothing about the security of the interpreter, and neither does a home page that loads normally.
Does it affect WordPress, PrestaShop, Laravel or only Apache?
What needs reviewing is the PHP running each application. Switching CMS or keeping plugins up to date does not show that the interpreter is fixed.
The PHP advisory covers any installation serving web requests, whether with PHP-FPM, Apache and mod_php, php-cgi, FrankenPHP or LiteSpeed. The level of available evidence differs between them, but the need to patch is the same for all:
| How PHP runs | What the advisories indicate | Priority (ekko’s assessment) |
|---|---|---|
Apache with mod_php |
Full exploitation validated for both CVEs; for the first, independent of the application | First |
| FrankenPHP | For the first CVE, source analysis suggests it is exploitable independently of the application | Immediately after |
| PHP-FPM | Susceptible to the first, with no complete exploit demonstrated; exploitation of the second validated through sessions | High |
| LiteSpeed (LSAPI) | Behaves like FPM; application-dependent attacks are considered likely, though not validated | High |
| php-cgi | Included in the general advisory; the technical advisories do not detail its case | High |
Where it is unclear which one a host uses, it is worth asking. Many shared hosting services run LiteSpeed or mod_php rather than FPM.
ekko’s proposed approach is to treat any internet-facing PHP application as pending action until its fix has been verified. Where a third party manages the application, evidence should be requested from them. For a site exported to HTML, the review should also extend to the editing back end and any auxiliary service still running.
None of this means every site can be exploited in the same way, or that any has been breached. A demonstrated attack does not prove an active campaign against a particular website, and the published advisories cannot certify the opposite either.
What can be done with access to the hosting control panel only?
The provider should be asked for the patch for both CVEs and a restart of the processes. Choosing “PHP 8.3” in the panel’s selector does not show which revision the site actually runs.
The panel is useful for recording the version assigned to each domain. If it offers a fixed, compatible revision, selecting it and testing the site is enough. If it only shows the branch, the full version number or the provider’s patch reference will have to be requested.
The following message can be sent to technical support as it stands:
Please confirm remediation of CVE-2026-109618 and CVE-2026-109619 for every domain in my account. Provide the complete PHP package revision or backport reference, how PHP runs for each domain (mod_php, PHP-FPM, LiteSpeed or other), and confirm replacement of all running PHP workers. If pending, provide an estimated completion time, whether you have applied the interim measures from the PHP advisory (session.upload_progress.enabled=0, memory_limit and request size limits) and a way to restrict requests before they reach PHP.
It is a template; ekko has not sent it to any provider.
A reply such as “WordPress is up to date” leaves the question unanswered. “The WAF blocks it” does not settle it either, and in that case it is worth pressing for the patch status. The ticket should be kept as evidence, together with the checks carried out afterwards.
How is a VPS updated without confusing command-line PHP with web PHP?
Packages, services and the mapping of each domain should be inventoried before updating. The version shown in the terminal may not match the one used by Apache or PHP-FPM.
On Debian or Ubuntu systems managed with APT, these commands only query the system and change nothing:
php -v
php --ini
dpkg-query -W 'php*' 'libapache2-mod-php*'
systemctl list-units --type=service --all 'php*-fpm.service'
php -v identifies only the command-line executable. The socket or back end for each virtual host has to be found in the web server configuration. Some panels also install their own binaries outside the system package manager.
The following example applies only to Ubuntu 24.04 with PHP 8.3-FPM from the official repositories, without a panel managing PHP. On any other server, packages and services will need adapting to whatever the inventory has revealed:
sudo apt-get update
apt-cache policy php8.3-fpm php8.3-common
sudo apt-get -s install --only-upgrade php8.3-fpm php8.3-common
Before continuing, the candidate version should be checked for the patch and the simulation reviewed. Any other installed PHP packages that the provider’s notice lists as affected must be included. Then:
sudo apt-get install --only-upgrade php8.3-fpm php8.3-common
sudo php-fpm8.3 -t
sudo systemctl restart php8.3-fpm
systemctl is-active php8.3-fpm
A restart can cut off requests in progress, so where there are several replicas it is advisable to take them out of the load balancer and update them in turn. If the configuration test fails, the error has to be resolved before restarting. mod_php follows a different procedure: the Apache module must be updated and Apache restarted, since restarting FPM leaves it untouched. On servers administered through a panel, the panel’s own mechanism should be used so as not to mix repositories.
On Debian, RHEL, their derivatives or hand-compiled installations, the reference is each vendor’s advisory and packages. APT or DNF finding no updates does not prove the patch is installed; the repository, the revision or support itself may be missing.
How is it handled in Docker, Kubernetes or Windows?
The artefact containing PHP must be updated and the running processes replaced. Downloading a new image does not, on its own, renew the active service.
In Docker, the first task is to establish where PHP comes from: an official image, a WordPress image, a custom image or an embedded binary. An image whose fixed revision can be verified should then be chosen, and the pinned tag or digest changed, since pulling an old digest again returns exactly the same artefact.
For a Compose service called web that already points to the fixed image and keeps its data in persistent volumes:
docker compose pull web
docker compose up -d --no-deps --force-recreate web
docker compose ps web
Docker’s own documentation states that compose pull only downloads the image; the container has to be recreated. With custom images, the process involves updating the base image, rebuilding and deploying. down -v should not be used: it deletes volumes and has nothing to do with patching.
In Kubernetes, the workload’s digest is updated, the rollout monitored and every replica verified, keeping the availability policies that have already been tested. One replica reporting the new version does not mean the whole cluster is fixed.
On Windows with IIS, the first step is to locate the FastCGI executable actually in use. The fixed build matching the architecture, the TS or NTS variant and the required extensions is then installed, the configuration preserved and the associated processes restarted. Swapping in individual DLLs from a different build is a bad idea. For packaged products, the updated package should be requested from the vendor.
What urgent measures can be applied if updating is not possible today?
The first step is to isolate the service, where that can be done. If the site must stay online, the official measures for each CVE are applied in startup configuration and every process restarted.
The PHP security advisory is clear: only an update resolves the problem completely. The measures below block specific attack paths without making the installation safe. They are best treated as a bridge of hours or a few days, with a record of who applied them, when, and the date by which they should be removed.
1. Block requests before they reach PHP
CERT-EU recommends isolating the service when it cannot be fixed straight away. The option ekko proposes is a static maintenance page or an IP restriction at the proxy or web server, having first checked that no alternative origin or port remains exposed.
A maintenance plugin comes too late. With mod_php, the first flaw is triggered before any application code runs, and the same applies to access protected only from within the application.
If the site runs on mod_php and the patch is going to take time, moving it to PHP-FPM removes the demonstrated attack path that does not depend on the application, because FPM terminates the process when request startup fails. This is ekko’s conclusion from the advisory, not a recommendation from PHP. FPM remains vulnerable, so the change reduces the risk without taking the place of the patch.
2. Against CVE-2026-109618 (out of memory)
These are the criteria from the PHP advisory and its technical advisory:
- Set
memory_limit=-1in a way the application cannot override, throughphp_admin_valuein the FPM pool or the Apache configuration, and verify that no pool, directory or application restores a finite limit. This removes the memory failure an attacker can control, although a genuine allocation failure would still reach the vulnerable path. - Lower
post_max_sizeto 8M where the application takes no file uploads and to 32M where it needs them, always keepingupload_max_filesizebelow that value. - Limit, at the web server or proxy, the decoded request size, the number of fields, multipart parts and headers per part, as well as the nesting depth. These limits must also apply to requests without a usable
Content-Length. In PHP,max_input_nesting_levelshould be reduced andmax_input_varsleft no higher than it is. - Block
multipart/form-datasubmissions at the front end when the application does not use them, so that they never reach PHP. - Set a container or cgroup memory limit as an availability safeguard, preferably with a policy that terminates only the affected process.
- Never rely on
RLIMIT_ASorRLIMIT_DATA, which cause exactly the allocation failure along the vulnerable path.
Applying memory_limit=-1 on its own would be a mistake. It would trade remote code execution for an outage, since a single client could exhaust the server’s memory. The measures work together.
3. Against CVE-2026-109619 (stale global state)
Criteria from the PHP advisory and its technical advisory:
- Disable
session.upload_progress.enabled(value0) inphp.ini, the FPM pool or the server configuration, and restart every process. This closes the confirmed paths through sessions, though not the other variants. Very few sites use this feature, and PHP suggests keeping it disabled even after patching. - On PHP 8.5, set
fatal_error_backtraces=0and restart every process. This blocks the best-documented case, which underpins the attack demonstrated againstmod_php. - Remove invalid or deprecated directives applied on each request that emit warnings before initialisation. The next section explains how to find them.
- Fix fatal errors and execution timeouts that a visitor could trigger, including those arising in callbacks, uploads, imports, error pages or cleanup tasks.
- Consider
pm.max_requests=1where performance is not a priority. Each FPM process then handles a single request and state no longer carries over, at the cost of high CPU usage; it only makes sense for low-traffic sites.
Neither ini_set() from the application nor FPM’s .user.ini, which applies after initialisation, works as early protection. Hiding warnings with error_reporting, display_errors or @ does not help either, because the state is read before PHP decides whether to show the message. A WordPress security plugin is equally out of the picture.
Example for PHP-FPM on Debian or Ubuntu
The following lines go at the end of the pool serving the domain, for example /etc/php/8.3/fpm/pool.d/www.conf. It is a starting point rather than a universal recipe; if the site accepts uploads, the sizes will need adjusting.
; Interim measures for CVE-2026-109618 and CVE-2026-109619
; Owner: ___ Applied: ___ Remove or review after patching
php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 8M
php_admin_value[upload_max_filesize] = 6M
php_admin_flag[session.upload_progress.enabled] = off
; PHP 8.5 only:
; php_admin_flag[fatal_error_backtraces] = off
The service memory limit can be set with a systemd drop-in file at /etc/systemd/system/php8.3-fpm.service.d/memory.conf:
[Service]
MemoryMax=2G
OOMPolicy=continue
MemoryMax sets the ceiling for the whole service and should be sized to the server’s memory. The directive that really matters is OOMPolicy=continue. Under systemd’s default policy, if the kernel terminates a process for lack of memory, the entire service is stopped; with this setting, only the affected process goes down and the FPM master replaces it. Then:
sudo php-fpm8.3 -t
sudo systemctl daemon-reload
sudo systemctl restart php8.3-fpm
Example for Apache with mod_php
These directives belong in the VirtualHost or in apache2.conf, never in .htaccess:
<IfModule php_module>
php_admin_value memory_limit -1
php_admin_value post_max_size 8M
php_admin_value upload_max_filesize 6M
php_admin_flag session.upload_progress.enabled off
</IfModule>
With mod_php, this configuration is applied on every request, and a mistyped value would produce precisely the kind of early warning the second flaw exploits. The values should therefore be copied exactly as shown, Apache restarted with sudo apachectl configtest && sudo systemctl restart apache2, and the error log checked to confirm that no new warning has appeared.
Example limits in nginx
# In the server {} block that passes requests to PHP
client_max_body_size 8m;
location ~ \.php$ {
# Only if the site takes no file upload forms
if ($content_type ~* "multipart/form-data") { return 415; }
# ... existing fastcgi_pass and remaining configuration
}
client_max_body_size also limits bodies sent in chunks without Content-Length. Its Apache equivalent is LimitRequestBody. Neither nginx nor Apache, however, can limit the number of parts, headers per part or nesting depth with their standard directives; that requires a WAF able to inspect multipart submissions. Where no such WAF is available and the site takes no uploads, blocking multipart covers all three limits at once. In WordPress, the admin media library relies on multipart. There are two options: restrict /wp-admin/ by IP and exempt it from the block, or forgo uploads while the measures are in place.
How can the configuration that triggers the second flaw be found?
The search is for PHP directives applied on each request that emit warnings. Any warning raised before initialisation, even one never displayed or logged, can consume the stale state.
According to the technical advisory, per-request configuration arrives through these routes:
- With
mod_php, through.htaccessand thephp_value,php_flagandphp_admin_*directives Apache applies per directory. This is the most direct route. - With PHP-FPM, only when nginx,
mod_proxy_fcgior another front end sendsPHP_VALUEorPHP_ADMIN_VALUE, which some panels do automatically. Pool values are applied when each process starts and.user.iniafter initialisation, so neither falls into this category. - With LiteSpeed (LSAPI), which may apply INI values taken from the environment early on, making it a possible though unconfirmed case.
- Normal
php.iniis read at startup and is not reapplied on each request.
On Debian or Ubuntu, the inventory can be done as follows (paths will need changing if a panel stores sites elsewhere, such as /home/*/public_html):
grep -RInE 'php_(admin_)?(value|flag)' /etc/apache2 /var/www
grep -RInE 'PHP_(ADMIN_)?VALUE' /etc/nginx /etc/apache2
Based on the technical advisory’s examples, the following values emit warnings:
- Deprecated directives:
auto_detect_line_endings=1; a non-defaultfilter.default; from 8.3, legacyassert.*directives; from 8.4, legacy session directives such assession.sid_lengthorsession.sid_bits_per_character; and on 8.5,report_memleaks=0or a non-zerointl.error_level. - Any explicit value for
mbstring.http_input,mbstring.http_output,mbstring.internal_encoding,iconv.input_encoding,iconv.output_encodingoriconv.internal_encoding. - Invalid or conflicting values for
zend.assertions,memory_limit,date.timezone, DBA, EXIF, mail, OpenSSL, zlib and loaded extensions. - From PHP 8.2, malformed or overflowing quantities for memory, body size, input, timeouts or stack. A correct
php_value upload_max_filesize 64Memits no warning; written as64MB, it does. - Log, mail, session or SOAP cache paths rejected by
open_basedir.
Legitimate configuration should be moved to php.ini or the FPM pool, which apply at startup, and deprecated directives removed.
Log review. On an isolated copy, or during a controlled window, log_errors=On, a working error_log and error_reporting=E_ALL are enabled in startup configuration. The Apache, PHP-FPM, proxy and system logs are then reviewed for:
- warnings, deprecations and core errors repeated before the script runs;
- warnings emitted during extension or server cleanup;
- fatal errors, parse errors and uncaught exceptions;
Maximum execution time exceededmessages;- failures that occur only on routes, content types, files or plugin options a visitor can control.
Fixing whatever turns up is necessary, but a clean log guarantees nothing. Historical logs may have been collected without deprecations, E_ALL only covers the routes exercised during the test, and a failure can occur before PHP manages to write the message. This review complements the patch and does not allow the incident to be closed.
How can it be confirmed that the fix is complete?
The incident is closed with evidence of the fixed package, the restarted processes and the correct operation of each domain. A home page that loads is not sufficient.
ekko suggests recording the following for each domain:
| Evidence | What to keep |
|---|---|
| Interpreter | SAPI, version and path of the real service |
| Fix | Complete package revision or digest, and the advisory covering both CVEs |
| Activation | Time of the restart or deployment, and replicas checked |
| Interim measures | Directives applied, location, time and planned removal date |
| Operation | Sign-in, forms, uploads, scheduled tasks and a test purchase where relevant |
| Owner | Person or provider ticket, and time of validation |
The check can use an existing, restricted diagnostic screen or a temporary endpoint protected at the web server itself, so that no unauthorised request reaches PHP. Where minimal code is needed for that endpoint:
<?php
header('Content-Type: text/plain; charset=utf-8');
echo PHP_VERSION, "\n", PHP_SAPI, "\n";
foreach ([
'memory_limit',
'post_max_size',
'upload_max_filesize',
'session.upload_progress.enabled',
'fatal_error_backtraces',
] as $k) {
echo $k, ' = ', var_export(ini_get($k), true), "\n";
}
The ini_get() lines show the values actually applied by the web process, not those of the terminal, and confirm on each back end that the interim measures are active. fatal_error_backtraces only exists on 8.5; on earlier branches the output will be false. The query should bypass caches and be repeated on each back end, and the endpoint must be removed afterwards. Publishing phpinfo() is not an acceptable alternative. The version number also has to be matched against the package, since on its own it does not reveal backports; and behind a load balancer, a single request does not verify every node.
If the update breaks a feature, the right course is to keep the service restricted while the incompatibility is resolved. Reverting to the vulnerable version and reopening the site cannot be considered a solution.
What should be done if an earlier intrusion is suspected?
The patch closes the vulnerability but does not undo a previous intrusion. Before cleaning or rebuilding, the service should be isolated and the evidence preserved.
As a procedure, proxy, server and PHP logs should be retained, along with the process inventory, file system changes and panel activity, complete with timestamps and time zone. A server snapshot is useful, although it does not prove the system is clean.
The next step is to look for departures from normal behaviour: unexpected child processes, unknown outbound connections, new files, and users or scheduled tasks that nobody has authorised. These are general signals rather than indicators specific to these CVEs. A single memory error does not prove exploitation, just as the absence of errors does not prove the system is secure.
If compromise is confirmed, the appropriate response is to rebuild from a trusted base, restore verified data and, from a clean environment, rotate every credential the affected service could reach. A scan of WordPress files does not necessarily cover the rest of the system, and in such a case whoever handles incident response should be involved.
Why is ekko’s website not exposed to these flaws?
ekko’s website generates its HTML at build time and does not need PHP to serve its pages, so the vulnerable interpreter plays no part in any visit.
In this project, astro.config.mjs declares output: 'static' and includes no runtime adapter. Content is validated and compiled before publication, and the result is a set of files that the server delivers without starting a CMS, querying a database or interpreting PHP on each visit.
The protection against these two flaws comes solely from not using PHP to serve these pages. The content security policy, local assets and the absence of framework JavaScript are part of ekko’s technical discipline, but they offer no protection against a vulnerability in the interpreter.
The scope should be stated precisely. The site’s code does not prove that the hosting account has no PHP, nor that a webmail service, control panel or neighbouring domain is patched; those components need their own inventory and isolation. A static site still requires protection of the server, DNS, credentials and publishing pipeline. Nor is it claimed that every ekko client project shares this architecture.
The principle ekko follows is not to keep capabilities in production that the business does not need. Where there are payments, user accounts or dynamic processes, they are designed with defined limits and maintenance. Where the task is simply to publish content, there is little sense in adding an internet-facing interpreter that rebuilds every page on every request.
For those who depend on PHP today, the priority is to patch and verify, not to migrate in a hurry in the middle of an emergency. Once the urgency has passed, ekko can review which parts of a website genuinely need dynamic execution and which can become static files, with the aim of reducing maintenance and attack surface through decisions that can be verified.
What else do people ask about this?
What is CVE-2026-109618?
A critical PHP vulnerability, rated CVSS v4.0 9.2 and published as GHSA-w8hw-w9fx-j79w under the name "RCE via OOM corruption". When a request runs out of memory, PHP can be left holding partially initialised internal data, which it later uses while closing the request. This allows code execution without authentication; against Apache with mod_php it was demonstrated before the application had even started. It is fixed in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35.
What is CVE-2026-109619?
A critical PHP vulnerability, rated CVSS v4.0 9.2 and published as GHSA-6wmf-4rv5-p3rp under the name "RCE via stale global state". A PHP process keeps references to memory belonging to a request that has already been freed, and the next request it handles makes use of them. This use-after-free allows unauthenticated code execution and memory disclosure, and exploitation has been validated against both mod_php and PHP-FPM. The same releases fix it.
Which PHP versions fix CVE-2026-109618 and CVE-2026-109619?
Versions 8.5.12, 8.4.27, 8.3.36 and 8.2.35, released on 21 October 2026. Linux distributions may ship the fix on top of an older base version with a new package revision, as Ubuntu 24.04 does with 8.3.6-0ubuntu0.24.04.13. There is no official release for PHP 8.1 and older, so those installations need a vendor backport or a move to a supported branch.
Does it affect PHP-FPM or only Apache with mod_php?
Any installation serving web requests is affected, whether it runs PHP-FPM, mod_php, php-cgi, FrankenPHP or LiteSpeed. The risk is greatest with mod_php, since there the first flaw can be exploited before the application runs. PHP-FPM has validated exploitation of the second flaw and is considered susceptible to the first as well.
Does updating WordPress protect a site from these vulnerabilities?
No. The flaw lies in the PHP interpreter rather than in WordPress or its plugins, so an up-to-date WordPress running on unpatched PHP remains exposed. It is the PHP package behind the site that has to be updated, followed by a restart of all its processes. The same holds for PrestaShop, Laravel, Drupal and any other PHP application.
What can be done if PHP cannot be updated today?
The prudent step is to isolate the service before requests reach PHP. Where the site has to stay online, PHP suggests several measures in startup configuration: session.upload_progress.enabled=0, fatal_error_backtraces=0 on PHP 8.5, and memory_limit=-1 enforced through php_admin_value, combined with a low post_max_size and request limits at the proxy. Every worker must then be restarted. These measures reduce the risk, although they do not replace the patch.
Are PHP 7.4, 8.0 and 8.1 affected?
Yes. Those branches no longer receive releases from the PHP project, but given the severity, minimal source patches have been published for 7.4, 8.0 and 8.1, aimed at those who build PHP themselves or have no LTS vendor. On managed hosting, the sensible course is to ask the provider for a verified backport or to move to a supported branch.
How can the PHP version a website actually runs be identified?
Neither php -v in a terminal nor the panel's selector is reliable here, because they show the command-line PHP or the selected branch rather than the revision serving the site. The real service behind each domain (the PHP-FPM socket, the Apache module or LiteSpeed) and its complete package need to be checked, or a temporary, protected endpoint can be queried to print PHP_VERSION and PHP_SAPI.