At a Glance

Your systems

Are you affected?

If you run PHP that serves web requests (PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP or LiteSpeed) and it is older than 8.2.35, 8.3.36, 8.4.27 or 8.5.12, assume you are affected. This includes applications built on PHP such as WordPress, Drupal, Magento and Laravel.

TR7 products

Is TR7 affected?

No. TR7 appliances have no PHP component that processes HTTP requests, so TR7 products are not affected by these vulnerabilities. Details are in Is TR7 Affected?.

Action

What to do now

  1. Update PHP on your web application servers and restart every PHP worker.
  2. Apply the temporary PHP settings below on those servers if you cannot update today.
  3. Until the update is complete, apply the core protection settings in TR7 WAF-WAAP; putting your PHP applications in Blocking mode is the first of them.

Key Facts

Advisory IDTR7-SA-2026-001
NamePHP2Shell
CVEsCVE-2026-109618 (remote code execution via out-of-memory corruption),
CVE-2026-109619 (remote code execution via stale global state)
Official advisoriesPHP Security Team announcement
GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)
SeverityCVSS v4.0 9.2, Critical (PHP Security Team)
Authentication requiredNo
Fixed versionsPHP 8.2.35, 8.3.36, 8.4.27, 8.5.12
Older branchesThe PHP Security Team published source backports for PHP 7.4, 8.0 and 8.1. Linux distributions provide their own patched packages.
ExploitationExploitation attempts are being reported. A successful compromise had not been publicly confirmed as of October 22, 2026.
CISA KEVNot listed as of the October 21, 2026 catalog

What Happened

  • October 20, 2026 Details of the vulnerabilities became public before the coordinated release.
  • October 21, 2026 The PHP project released fixed versions and published the advisories GHSA-w8hw-w9fx-j79w and GHSA-6wmf-4rv5-p3rp.
  • October 21-22, 2026 Exploitation attempts were reported, and public proof-of-concept code appeared.

How the Attack Works

Both vulnerabilities are in PHP itself, not in application code. The attack happens while PHP is still reading the incoming request, before any line of your application runs. Updating WordPress, a plugin or your own code does not fix it.

  • CVE-2026-109618 abuses the moment PHP runs out of memory. Attackers send requests that force PHP to use a lot of memory while it parses form data and file uploads, so that PHP stops in an unsafe state.
  • CVE-2026-109619 leaves stale data behind in a PHP worker after one request, and a second request to the same worker uses it. One documented path uses PHP's session upload progress feature, which is enabled by default and is triggered by a form field named PHP_SESSION_UPLOAD_PROGRESS.

Because the requests that carry these attacks are mostly multipart/form-data (file upload) requests, large request bodies and repeated requests, a web application firewall can see and restrict many of them. It cannot see what happens inside PHP's memory.

Is TR7 Affected?

These vulnerabilities are in PHP's own request handling layer and affect application servers that run PHP. TR7 appliances have no PHP component that processes HTTP requests, so TR7 products are not affected by these vulnerabilities.

What You Should Do Now

The work is in two places: your own web application servers that run PHP, and TR7 WAF-WAAP. Each section numbers its own steps.

On your servers

Step 1: Update PHP on your web application servers (the only complete fix)

  1. Update PHP on the servers that run your web application to 8.2.35, 8.3.36, 8.4.27 or 8.5.12, or install your Linux distribution's patched package. Distribution packages often keep the old version number; check the package changelog for the CVE numbers.
  2. Restart every PHP worker (PHP-FPM pools, Apache, LiteSpeed, long-running workers). Running processes keep using the old code until they restart.
  3. Rebuild container images that include their own PHP. Updating the host does not update PHP inside an image.
  4. PHP 8.1 and older no longer receive updates from the PHP project. Plan an upgrade to a supported branch.

Step 2: Temporary PHP settings on your web application servers (if you cannot update today)

These settings are made in the PHP configuration of the server that runs your web application (php.ini or PHP-FPM pool settings). The PHP Security Team lists these measures. They reduce exposure to specific attack paths but do not make an installation safe.

SettingPurpose
session.upload_progress.enabled = 0Removes the session upload progress path of CVE-2026-109619. Restart all workers. The PHP Security Team suggests keeping it off after patching if you do not need it.
fatal_error_backtraces = 0 (PHP 8.5)Removes the fatal error backtrace path
post_max_size = 8M (no uploads) or 32M (uploads), with upload_max_filesize lowerReduces the memory an attacker can force PHP to use
memory_limit = -1, set with php_admin_valueRemoves the controllable memory limit failure. One request can then use all server memory; use container or cgroup limits, never RLIMIT_AS or RLIMIT_DATA

On TR7 WAF-WAAP

If you can update PHP right away, that is the real fix. If you cannot, until the update is complete you can protect your PHP applications against these attacks with the security settings TR7 WAF-WAAP already provides, without any TR7 update. The three settings in Step 1 are the core protection; the additional measures in Step 2 narrow the attack surface further, so choose the ones that fit your application. Apply the settings per vService and try them on a non-production vService first.

Step 1: Core protection

1.1 Put the WAF in Blocking mode

A WAF that only monitors does not stop an attack. When the WAF is first enabled it starts in Learning mode; Monitor mode only records. For each PHP vService, open the WAF Mode screen and confirm it is in Blocking mode.

Caution: Before you switch, review the signature exclusions learned on each field. If the exclusions on a field exceed the Max. owasp exclusions value, signature inspection is turned off for that field.

1.2 Add two custom rules

On the Signature & Rule Library screen (WAF → Signature & Rule Library → Add), add the two rules below separately. Start both in the Monitor state and change them to Enabled after reviewing Event Logs. The rules apply to every WAF-protected vService.

Rule 1: Session upload progress field

  • Pattern (Regex): PHP_SESSION_UPLOAD_PROGRESS
  • Inspection Scopes: Form and Raw
  • Score: Very High

Catches the form field that triggers the session upload progress path of CVE-2026-109619. For applications that legitimately use this feature, exclude only the upload paths that need it.

Rule 2: PHPSESSID form field

  • Pattern (Regex): ^PHPSESSID$
  • Inspection Scopes: Form
  • Score: Very High

Catches requests that carry the session ID in a form field named PHPSESSID instead of a cookie; some attack paths use this form, and it is rare in legitimate traffic. If your application uses a different session name (session.name), use that name.

For the rules to work: The rules are scanned with the Form and RAW inspections of the page type that matches the request. On a page type without a Form inspection, form and file upload bodies are not scanned.

  • Keep OWASP check on in the Any Paths rule and in page types that have their own Form or RAW inspection.
  • Add its own Form and RAW inspection to every glob page type with the Add common rule for Form and Add common rule for Raw buttons; do not rely on inherited settings.
1.3 Block large and uninspectable bodies

On the WAF Rules screen, make two settings in the RAW inspection:

  1. Set Raw Body Size to the largest body the path needs (in bytes; for example 8388608 = 8 MB on paths without uploads, 33554432 = 32 MB on upload paths). The default range allows bodies up to 256 MB.
  2. Switch the unparsed body toggle from Allow unparsed body to Block unparsed body. Otherwise a body that does not fit the inspection buffer is forwarded to the Backend Service without any content inspection.

Where? The WAF inspects a request only with the settings of the page type that matches its path. Make these two settings on the Any Paths rule, on every page type that shows Raw in the Check Fields column, and on every glob page type; add a RAW inspection first with Add common rule for Raw to a glob page type that has none.

Caution: Raw Body Size applies while Structure Checks is on, on the Checks screen. Test legitimate large uploads first. Bodies sent without a declared length are not measured by this limit; on paths outside the upload paths they can be blocked with 2.1.

Step 2: Additional measures

These measures complement the core protection; choose the ones that fit your application.

2.1 Block file uploads where you do not need them

Attack requests are mostly multipart/form-data (file upload) requests. If only a few paths in your application accept files, block multipart requests to every other path with a load balancer rule. The rule consists of two conditions and a Block action. All screens are reached from the Configuration Menu, opened with the TR7 logo at the bottom left.

A. Create the conditions (Load Balancer → Conditions → Add)

  1. Multipart request condition: Criteria = HTTP header, matching method Includes, Header Name = Request → Content-Type, Query = multipart/form-data, Case Insensitive on. Enter a Condition Name such as multipart-request and save with Add.
  2. Upload paths condition: Criteria = Path, matching method Regex, and in Query enter the paths that accept files (for example ^/(upload|media/upload)). Enter a Condition Name such as upload-paths and save with Add.

B. Create the Block action (Load Balancer → Actions → Add)

  1. Enter an Action Name (for example block-multipart), Action Type = Block, Execution Level = On Request, Deny Type = Standard, Status Code = 403.
  2. In Conditions, select multipart-request and !upload-paths in the same condition group (default and). Every condition appears in the list twice: itself and its negation (NOT) starting with !; !upload-paths means "not one of the upload paths".
  3. Turn on Hit Counter to count blocked requests and save with Add.

C. Add the action to the vService

  1. On Load Balancer → Load Balancer vService List, select the vService and click Edit, select the action in Actions under Details, and click Save.

D. Also block bodies sent without a declared length

  1. Create another HTTP header condition: matching method Is present, Header Name = Request → Content-Length, Condition Name for example has-length.
  2. Create a second Block action (On Request, Standard, 403). In Conditions, select the predefined If HTTP method is POST condition, !has-length and !upload-paths in the same condition group, and add the action to the vService Actions field. The POST condition is required; without it, GET requests without a body are blocked too.

The size limit in 1.3 does not see the real size of a body sent without a declared length. This rule covers both HTTP/1.1 streamed (chunked) uploads and HTTP/2 bodies without a declared length on paths outside the upload paths. POST requests with no body and no Content-Length header also match this rule; try it on a non-production vService first.

Verify: A multipart request (curl -s -o /dev/null -w '%{http_code}\n' -F 'a=b' https://www.example.com/), an HTTP/1.1 chunked request (curl -s -o /dev/null -w '%{http_code}\n' --http1.1 -H 'Transfer-Encoding: chunked' -d 'a=b' https://www.example.com/) and an HTTP/2 request without a declared length (printf 'a=b' | curl -s -o /dev/null -w '%{http_code}\n' --http2 -X POST -T - https://www.example.com/) to a path outside the upload paths should get 403, and requests to your upload paths should pass. --http1.1 is required for the HTTP/1.1 test: curl uses HTTP/2 over https by default and does not send Transfer-Encoding over HTTP/2. The counter appears on the Action Hits tab of the vService dashboard.

Caution: A Block action with no condition selected applies to every request to the vService. List all upload paths completely and try the rule on a non-production vService first.

2.2 Limit POST requests per client

This rule does not stop a targeted attack: the exploit can work with only a few requests. It does raise the cost of automated tools that try many targets. The rule counts the POST requests of each client IP and blocks the POST requests of a client over the threshold with 429. The block lifts by itself when the counter drops below the threshold.

A. Create the counter action (Load Balancer → Actions → Add)

  1. Enter an Action Name, Action Type = Advanced Traffic Inspection, Fields to Track = Client IP address, Traffic Tag = for example post-rate (3-20 characters; letters, digits, -, _), Tracking Period = 1 minute.
  2. In Conditions, select the predefined If HTTP method is POST condition and save with Add. Only POST requests are then counted.

B. Create the threshold condition (Load Balancer → Conditions → Add)

  1. Criteria = Tracking Condition, Tracked Table = post-rate, Tracking Criteria = HTTP requests, and the threshold with Tracking Operator (for example > 100). Save with Add.

C. Create the Block action (Load Balancer → Actions → Add)

  1. Action Type = Block, Execution Level = On Request, Deny Type = Standard, Status Code = 429.
  2. In Conditions, select the threshold condition from step 3 and If HTTP method is POST in the same condition group (default and). Without the POST condition, the GET requests of a client over the threshold are blocked too. Save with Add.

D. Add the actions to the vService

  1. In the vService Edit form, in Details → Actions, select the counter action first and the Block action second, and click Save. Actions run in list order.

Verify: On the vService Logs & Tracking tab, select the counter action's tracking table in the Logs Type list; POST counters per client are shown. Set the threshold from your application's normal traffic: observe the POSTs per minute of legitimate clients (for example systems using an API, or organizations behind a shared outbound IP) in the table and set the threshold above them.

2.3 Set L7 DDoS protection to Active

If Bot/DDoS protection is in your license, Source IP Request Protection under L7 DDoS Protection limits the total number of requests a single source address can make in a period. Unlike 2.2, it counts all requests and needs no extra rule.

  1. In the vService Edit form, select L7 DDoS & Threat Protection under Details and click Save (if it is not on). When protection is turned on, L7 DDoS Protection starts in Monitor mode; in this mode limit violations are only recorded as events.
  2. On Left Monitor Panel → Bot/DDoS Protected vServices → vService → Bot/DDoS Management, click the Edit link on the L7 DDoS Protection card.
  3. Set DDoS Protection = Active and save with the Edit button.
  4. On the card, click the pencil icon of the Source IP Request Protection block. Set Time Window (default 10 seconds), Request Limit (default 1000) and Limit Action (default Show Captcha; Block can also be selected) for your application's traffic and save with the Edit button.

Caution: Watch the events in Monitor mode for a while before switching to Active. Repeat the same observation when you lower the Request Limit.

Check whether you were targeted

See Detection and Monitoring. Exploitation attempts were reported before public disclosure, so review logs from October 17, 2026 onward.

What a WAF Can and Cannot Do

A WAF canA WAF cannot
Block known request shapes, such as the session upload progress fieldFix the vulnerable code inside PHP
Limit body size, upload paths and request ratesMeasure memory use inside the PHP process
Block uploads on paths that do not need themSee requests that reach your server without passing through it
Record blocked and rate-limited requestsUndo code that already ran on the server

WAF rules buy time for the update; the lasting fix is updating PHP. For these protections to work, all traffic to your PHP applications must pass through TR7 WAF-WAAP.

Detection and Monitoring

In TR7

  • On the Event Logs screen of each WAF-protected vService, filter the records by your custom rules and look at the matched field and score.
  • On the same screen, review the requests blocked by the body size and unparsed body rules.
  • If you applied the additional measures, watch the load balancer rule counters on the Action Hits tab of the vService dashboard, and the clients that hit the POST rate limit in the tracking table on the Logs & Tracking tab.

On your servers

  • Search the PHP error logs for errors such as Allowed memory size ... exhausted, worker crashes and repeated HTTP 500 responses; pay attention to those that come right after large multipart/form-data requests.
  • Check responses for unusually large or malformed PHPSESSID cookies.
  • Check web roots for new or changed files, and look for unexpected processes started by the web server user, new cron jobs and unexpected outbound connections.

FAQ

No. TR7 appliances have no PHP component that processes HTTP requests, so TR7 products are not affected by these vulnerabilities. See Is TR7 Affected?.

No WAF can fully protect against these vulnerabilities. TR7 WAF-WAAP reduces the attack surface and blocks known attack paths; updating PHP is the only complete fix.

Use the two custom rules in TR7 WAF-WAAP 1.2 against PHP2Shell; they apply to all WAF-protected vServices immediately.

No. The vulnerabilities are in the PHP runtime. Update PHP itself, or ask your hosting provider to do it.

They can. Body size limits, upload blocking and the custom rules may affect legitimate uploads and forms. For WAF rules, start in Monitor mode, review Event Logs, then switch to Blocking mode. Try load balancer rules (2.1, 2.2) on a non-production vService first.

Update History

  • Oct 23, 2026 Initial publication.

References

Need help applying these settings?

The TR7 Support Team can review your WAF configuration and help you deploy these protections. Contact your TR7 representative or the TR7 Support Team at support@tr7.com.