// web security

CVE-2026-115560: PHP’s Unpatched RCE Hinges on One Runtime Swap

Terminal grep for session.serialize_handler illustrating PHP's unpatched CVE-2026-115560 remote code execution risk

On October 23, 2026, PHP disclosed CVE-2026-115560, a new, still-unpatched remote code execution path that the project will not emergency-patch. Whether it affects you depends less on your PHP version than on whether your code swaps the session serializer at runtime, and a grep across code and configuration is the fastest place to start checking.

Key takeaways

  • CVE-2026-115560 is a new, unpatched PHP RCE path disclosed October 23, 2026, and PHP will fix it only in the next routine release.
  • Exposure requires php_binary or php_serialize in config, an ini_set() swap to php before session_start(), and upload progress still enabled.
  • The mitigation is one line, session.upload_progress.enabled=0, the same setting already recommended for CVE-2026-109619.
  • The October 21 releases (8.5.12, 8.4.27, 8.3.36, 8.2.35) fix PHP2Shell but do not fix CVE-2026-115560.
  • PHP2Shell attempts reached millions by October 22, with a pre-disclosure hit on October 17, but no code execution has been confirmed.

What did PHP actually publish on October 23?

PHP published a short informational advisory, not a security release. It assigns CVE-2026-115560 to a new remote code execution risk, calls it unlikely, and says it affects only web applications configured in an unusual way. No emergency build is coming. The fix will ship in the next routine bugfix release, and PHP will publish a full advisory at that point.

The timing matters. Two days earlier, on October 21, PHP shipped emergency releases 8.5.12, 8.4.27, 8.3.36 and 8.2.35 to fix the two PHP2Shell flaws, CVE-2026-109618 and CVE-2026-109619. Both let an attacker without an account run code on a server.

CVE-2026-115560 is a separate issue, and those October 21 releases do not fix it. The October 21 upgrades were necessary, but they do not close this path.

The advisory omits most technical and severity details. It does not list affected versions, name the release that will carry the fix, assign a severity score, or say whether the new bug shares a root cause with CVE-2026-109619.

What configuration makes CVE-2026-115560 reachable?

An application is exposed only if all of the following are true for the same request:

  1. The application’s configuration sets session.serialize_handler to php_binary or php_serialize.
  2. The application changes that value to php at runtime with ini_set().
  3. That change happens before session_start().
  4. Session upload progress is still enabled, which is PHP’s default.

The swap matters because the three handlers store session data in different formats. php_serialize uses the standard serialize() format, php_binary uses a binary encoding, and php uses the legacy delimiter-based format. PHP’s own documentation warns against mixing handlers when writing and reading session data. PHP has not explained how mixing these formats leads to code execution, and we won’t guess.

Upload progress belongs in the chain because it processes request data. When a multipart POST includes a field named PHP_SESSION_UPLOAD_PROGRESS (configurable through session.upload_progress.name), PHP writes upload metadata into the session under a key prefixed with upload_progress_. The application does not need to implement upload-progress tracking for this to happen.

Security researchers have previously used the feature in local-file-inclusion chains, where progress data planted content in session files. That is not evidence that CVE-2026-115560 works the same way.

PHP also states clearly when an application is not exposed: if it never changes the serializer at runtime, it is not reachable through this path, even with upload progress left on.

Is your PHP app exposed? Where to start the audit

Start by searching your code and your effective configuration for the handler swap. Include vendored framework bootstraps:

  • grep -rnE "serialize_handler" --include=*.php . to find literal ini_set() calls and any wrapper that builds the directive name dynamically.
  • Check php.ini, conf.d drop-ins, PHP-FPM pool files (php_value and php_admin_value), .user.ini and Apache php_value lines for php_binary or php_serialize.

Two traps can catch you. First, ini_set() only lasts for the current request, so global config can look clean while one code path still makes the switch. Finding the call also doesn’t prove every request reaches it.

Second, CLI and web configurations often differ. A clean php -i on the host tells you nothing about an FPM pool with its own overrides. Read ini_get() values from a controlled web request instead.

The mitigation is a single line, session.upload_progress.enabled=0, kept in place until the next routine bugfix release. Put it in the configuration your web workers actually load, then reload PHP-FPM or the web server. The October 21 advisory already recommended the same setting for CVE-2026-109619. If you applied that setting after the October 21 advisory and left it in place, you have nothing more to do for this CVE.

Practitioner’s note: in manual secure code review, runtime serializer swaps usually show up in older applications that share a session store with a second app or a legacy component expecting the old format. Some bootstrap file changes the handler and nobody remembers why. If your grep finds one, the swap deserves remediation on its own, independent of this CVE: two parts of your stack disagree about how session state is encoded.

Why does an 'unlikely risk' still deserve a ticket?

It deserves a ticket because PHP’s risk call depends on configuration you haven’t verified yet, and the advisory gives you nothing else to work from. With no version range, no severity score and no root-cause statement, you can’t triage this by CVSS or by build number. You have to check the code path.

The ticket can close once you rule out the swap or verify the mitigation from a web request. If the grep finds a swap, keep the ticket open until the fix ships and put the swap itself on the refactoring backlog. No exploitation of CVE-2026-115560 has been reported.

Is PHP2Shell being exploited in the wild?

The PHP2Shell flaws have drawn millions of exploitation attempts, but no code execution has been confirmed. The two patched flaws, CVE-2026-109618 and CVE-2026-109619, account for all the attack traffic reported since October 21.

  • October 17: Amazon honeypots logged an exploit attempt against both flaws, four days before public disclosure.
  • October 21: Cloudflare counted tens of thousands of attempts within 45 minutes of disclosure.
  • Early October 22: Cloudflare’s count reached millions.

Sophos and Arctic Wolf saw attackers try to install a Mirai botnet variant through the flaws. Previdian, Wordfence and others report only scanning and probing, and researchers say a reliable exploit is proving harder to build than expected. Treat these numbers as attempts, not as compromises or unique victims.

The reported mass-scanning surge followed disclosure, but the October 17 attempt means someone was probing these flaws before public disclosure. That shifts the start of any log review back by four days.

What to do this week

  1. Patch PHP2Shell first. Move every branch to 8.5.12, 8.4.27, 8.3.36 or 8.2.35.
  2. Run the serializer grep across application code and configuration, including FPM pools and per-directory overrides.
  3. Set session.upload_progress.enabled=0 until the fixed release ships, and verify it from a web request, not the CLI. Once the fix lands, keep it disabled only where nothing relies on upload progress.
  4. Hunt from October 17 onward, not October 21. Keep request bodies where policy allows, plus multipart field names, response codes and PHP-FPM logs. Look for child processes of PHP workers, newly written executables, outbound connections from PHP workers and persistence changes; these are stronger signals than a PHP_SESSION_UPLOAD_PROGRESS probe in a WAF log. Upload progress cleanup is on by default, so session files without progress data don’t prove the feature was never hit.
  5. Watch for the next routine PHP release and its full CVE-2026-115560 advisory, then revisit this ticket.

If you cannot say how quickly PHP releases reach your production edge servers, measure that separately. A web application penetration test that includes configuration and session-handling review can reveal session-handling weaknesses and configuration drift that a version check will miss.

FAQ

Does CVE-2026-115560 affect every PHP application?

No. PHP says it affects only apps that configure php_binary or php_serialize as the session serializer, switch it to php with ini_set() before session_start(), and leave upload progress enabled. Apps that never change the handler at runtime are not exposed through this path.

Does PHP 8.4.27 fix CVE-2026-115560?

No. The October 21 releases (8.5.12, 8.4.27, 8.3.36 and 8.2.35) fix the PHP2Shell flaws CVE-2026-109618 and CVE-2026-109619. CVE-2026-115560 is separate and will be fixed in the next routine bugfix release.

Which PHP versions are affected by CVE-2026-115560?

PHP has not said. The advisory gives no affected version list, no fix release identifiers and no severity score, so decide exposure from your configuration and code path rather than your version number.

Can I leave session.upload_progress.enabled=0 permanently?

Keep it disabled at least until the fixed release ships. After that, leaving it off is reasonable wherever nothing in your application relies on server-side upload progress tracking. The same setting also mitigates CVE-2026-109619.

Was CVE-2026-115560 exploited before the advisory?

No exploitation of CVE-2026-115560 has been reported. All reported attack activity targets the two PHP2Shell flaws, including an Amazon honeypot hit on October 17, four days before their public disclosure.

Did attackers get code execution with PHP2Shell?

Not as far as anyone has confirmed. Sophos and Arctic Wolf saw attempted Mirai botnet installs, while Wordfence, Previdian and others report only scanning and probing, and researchers say a reliable exploit is harder to build than expected.

If you want someone to trace session handling and configuration drift across your PHP estate before the next advisory, our AI-powered penetration testing combines automated analysis with human review to examine session handling and configuration across your PHP applications.


// get started

Work with AgentOffense

Tell us about your target and goals. We’ll reply with scope and a fixed-price quote — usually within one business day.

./request_engagement