PHP CVE-2026-115560: Demystifying the Post-PHP2Shell RCE Advisory
The CVE-2026-115560 advisory was issued by the PHP security team two days after emergency patches were deployed for PHP2Shell (CVE-2026-109618 and CVE-2026-109619). The attack vector involves the session.upload_progress feature paired with an unusual runtime switch of session.serialize_handler before session_start(). Default applications like WordPress and Laravel do not perform this runtime switch and are not vulnerable out of the box. As a universal defense across all Linux servers, administrators should disable the subsystem by setting session.upload_progress.enabled = 0 in php.ini until the routine patch arrives.
If you follow threat intelligence feeds and systems administration networks (such as cybersecurity_outlook), you may have witnessed sudden headlines proclaiming: “Two days after PHP2Shell, another unpatched 0-day RCE has emerged in the PHP core!”.
When such alerts break, engineering teams often vacillate between unnecessary panic and operational paralysis. In production infrastructure management, our responsibility is to separate social media sensation from verified technical mechanics.
This advisory directly expands upon the incident response doctrine established in our CISA, NSA & FBI Emergency Playbook: PHP, Node.js & Port Hardening and our field guide to cPanel, Plesk & Linux Servers: PHP2Shell & Port Lockdown.
At Webxtek Studio, where we engineer and defend hosting environments for cybersecurity & pen-testing firms and B2B enterprise SaaS platforms, we audited this vector directly within the PHP source engine. Below I examine the underlying serialization mechanisms, evaluate who is genuinely at risk, and provide one-liner commands to neutralize the attack surface in 60 seconds.
1. Technical Anatomy of CVE-2026-115560: Session Serialization Mismatches
To assess this vector objectively, you must understand how PHP handles file uploads in the background.
Since PHP 5.4, the runtime includes the directive session.upload_progress.enabled = 1 by default. When an HTTP client submits a multipart POST request containing a hidden field named PHP_SESSION_UPLOAD_PROGRESS, the low-level SAPI layer intercepts the upload stream before any userland application code executes.
To allow client-side scripts to poll upload progress, the interpreter writes telemetry keys directly into the $_SESSION superglobal:
Normal Upload Progress Sequence:
1. Client sends multipart/form-data POST with PHP_SESSION_UPLOAD_PROGRESS key.
2. FastCGI/SAPI layer intercepts the raw stream before user script runs.
3. PHP initializes session state and writes $_SESSION["upload_progress_" . $id].
4. Telemetry is serialized to disk or Redis based on session.serialize_handler.
The vulnerability arises in the internal serialization engine when three specific conditions occur simultaneously:
- Base Configuration: The host
php.inior virtual host configuration definessession.serialize_handlerasphp_binaryorphp_serialize. - Dynamic Runtime Switch: The application executes
ini_set('session.serialize_handler', 'php')dynamically before invokingsession_start(). - Active Subsystem: The
session.upload_progress.enableddirective remains active.
Under this exact sequence, PHP records the upload progress payload using one serialization format and subsequently attempts to deserialize the session state using a different parser. This formatting mismatch creates an asymmetric deserialization condition: an external attacker can manipulate session byte prefixes and inject forged serialized objects (POP Gadgets), resulting in arbitrary code execution inside the PHP worker process.
2. Social Media Hype vs. Operational Reality: Who is Vulnerable?
Labeling an advisory an “unpatched RCE” understandably triggers alarm. However, understanding why the PHP core team declined to issue an out-of-band emergency point release provides crucial context:
Operational Risk Comparison:
Vector: PHP2Shell (CVE-2026-109618 / 109619)
- Severity: CVSS 9.2 (Universal Critical)
- Condition: Any unpatched PHP host receiving multipart POST data
- Impact: Unauthenticated remote code execution on standard WordPress/Laravel
- PHP Action: Immediate emergency out-of-band releases (8.2.35, 8.3.36, 8.4.27)
Vector: CVE-2026-115560
- Severity: Informational Advisory (Edge-Case Configuration)
- Condition: Requires dynamic session.serialize_handler runtime switching before session_start()
- Impact: Restricted to bespoke apps toggling serialization engines in runtime
- PHP Action: Resolution scheduled in the regular monthly bugfix release
Is Your CMS or Framework Exposed?
- WordPress & WooCommerce: Not vulnerable by default. WordPress does not use PHP native upload progress for media library ingestion and does not toggle session serialization handlers dynamically.
- Laravel & Symfony: Not vulnerable by default. Modern frameworks manage sessions using proprietary abstraction drivers (database, Redis, or encrypted cookies) rather than native PHP session files.
- Bespoke Enterprise Systems & Legacy Code: If you maintain custom platforms relying on legacy upload libraries or codebases that programmatically toggle between binary session serializers, your exposure is real and requires immediate mitigation.
3. Immediate Terminal Mitigation: Securing Your Host in 60 Seconds
The official recommendation from the PHP security team is to disable the session upload progress subsystem entirely. In 2026, this feature is largely obsolete: modern web applications manage upload progress using direct client-side chunking, WebSockets, or presigned cloud storage URLs (such as S3) without placing burden on PHP session storage.
Step 1: Verify Current Runtime Status
Execute the following in your terminal to inspect the active configuration:
php -i | grep -E "session\.upload_progress\.(enabled|name)"
If the command reports session.upload_progress.enabled => On => On, your environment currently has the feature enabled.
Step 2: Disable on Debian, Ubuntu, and Bare-Metal Linux
For production hosts running PHP-FPM on Debian or Ubuntu:
# Disable upload progress across all installed PHP-FPM pools
for ini in /etc/php/*/fpm/php.ini; do
if [ -f "$ini" ]; then
echo "Hardening $ini..."
sudo sed -i 's/^session.upload_progress.enabled = .*/session.upload_progress.enabled = 0/' "$ini"
if ! grep -q "^session.upload_progress.enabled = 0" "$ini"; then
echo "session.upload_progress.enabled = 0" | sudo tee -a "$ini"
fi
fi
done
# Reload PHP-FPM workers to apply the change in memory
sudo systemctl reload "php*-fpm" || sudo systemctl restart "php*-fpm"
Step 3: Disable on HestiaCP, Plesk, and cPanel
If you administer multi-tenant hosting environments:
- HestiaCP:
Apply the restriction across all pool templates in
/etc/php/*/fpm/pool.d/:echo "php_admin_value[session.upload_progress.enabled] = 0" | sudo tee -a /etc/php/*/fpm/pool.d/*.conf sudo systemctl reload "php*-fpm" - cPanel with EasyApache 4:
Update
/opt/cpanel/ea-php*/root/etc/php.inior setsession.upload_progress.enabled = Offin the WHM MultiPHP INI Editor, then execute:/scripts/restartsrv_apache_php_fpm - Plesk:
for ini in /opt/plesk/php/*/etc/php.ini; do sed -i 's/^session.upload_progress.enabled = .*/session.upload_progress.enabled = 0/' "$ini" done systemctl reload "plesk-php*-fpm"
Step 4: Production Docker Containers
If you distribute containerized PHP applications, inject a dedicated hardening layer into your Dockerfile:
# Hardening against CVE-2026-115560 and PHP2Shell
RUN echo "session.upload_progress.enabled = 0" > /usr/local/etc/php/conf.d/security-hardening.ini \
&& echo "session.upload_progress.cleanup = 1" >> /usr/local/etc/php/conf.d/security-hardening.ini
4. Conclusion: Defense-in-Depth After PHP2Shell
The emergence of CVE-2026-115560 immediately after the global PHP2Shell emergency underscores an immutable principle of infrastructure security: whenever core runtime components undergo intensive public scrutiny, peripheral subsystems (session handlers, temp files, buffer management) inevitably experience secondary vulnerability discovery.
The only sustainable defense against interpreter flaws is proactive surface reduction:
- Deploy Patched Binaries: Keep production hosts updated to supported, patched releases (8.2.35+, 8.3.36+, 8.4.27+).
- Decommission Obsolete Directives: Enforce
session.upload_progress.enabled = 0globally. - Lock Administrative Ingress: Restrict management panel ports (cPanel 2083, Plesk 8443, HestiaCP 8083) behind
nftablesaccessible only through WireGuard, as detailed in our control panel mitigation guide. - Enforce Process Isolation: Run workers over isolated UNIX sockets and confine developer access using
chrootsandboxes, as documented in our HestiaCP Jailkit Guide.
By implementing these measures systematically, your production servers remain resilient against both zero-day exploits and secondary disclosure waves.
[+] [ INDEX_DIRECTORY ] 17 topics ▼
- 1. Technical Anatomy of CVE-2026-115560: Session Serialization Mismatches
- 2. Social Media Hype vs. Operational Reality: Who is Vulnerable?
- Is Your CMS or Framework Exposed?
- 3. Immediate Terminal Mitigation: Securing Your Host in 60 Seconds
- Step 1: Verify Current Runtime Status
- Step 2: Disable on Debian, Ubuntu, and Bare-Metal Linux
- Step 3: Disable on HestiaCP, Plesk, and cPanel
- Step 4: Production Docker Containers
- 4. Conclusion: Defense-in-Depth After PHP2Shell
- Author
- Frequently Asked Questions
- What is the PHP CVE-2026-115560 vulnerability?
- Are standard WordPress or Laravel installations vulnerable to CVE-2026-115560 by default?
- Why did the PHP project not publish an out-of-band emergency release like they did for PHP2Shell?
- What is the recommended temporary mitigation before the routine patch is published?
- Related Nodes
- Path Sequence
Frequently Asked Questions
What is the PHP CVE-2026-115560 vulnerability?
It is an informational security advisory issued by the PHP security team concerning a remote code execution (RCE) vector in the session.upload_progress subsystem. The issue triggers when an application configures session serialization to php_binary or php_serialize and subsequently modifies that directive at runtime to php using ini_set() prior to calling session_start().
Are standard WordPress or Laravel installations vulnerable to CVE-2026-115560 by default?
No. Mainstream content management systems and frameworks (WordPress, Laravel, Symfony, Drupal, and Magento) do not dynamically switch the session.serialize_handler at runtime before session_start(). The exposure primarily threatens bespoke enterprise platforms, legacy applications with custom file upload handlers, or third-party wrappers that alternate session serializers.
Why did the PHP project not publish an out-of-band emergency release like they did for PHP2Shell?
Because the specific configuration combination and runtime behavior required to exploit CVE-2026-115560 is uncommon across production workloads. The PHP core security team assessed the practical risk as low for the broader ecosystem and scheduled the permanent fix for the regular monthly bugfix release cycle.
What is the recommended temporary mitigation before the routine patch is published?
Disable the session upload progress subsystem by setting session.upload_progress.enabled = 0 in your php.ini or PHP-FPM pool configurations. If you already implemented the complete PHP2Shell hardening playbook recommended by Webxtek Studio, this directive is already disabled and your server is completely protected.
[ RELATED_NODES ]
> START_PROJECT
Need a website that earns trust, ranks in search, and gives your business a stronger digital presence? Start the conversation here.