رأس القلم

CVE-2026-115560: PHP Upload Progress Risk and Checks

CVE-2026-115560 PHP upload progress risk and checks with the original transparent Penligent logo
Configuration review based on PHP’s October 23 informational advisory.

CVE-2026-115560 is PHP’s newly disclosed session upload progress issue. On October 23, 2026, PHP recommended disabling session.upload_progress.enabled until the next regular bugfix release. The advisory describes an unusual configuration-and-code combination, rather than a universal RCE condition across all PHP websites. PHP’s informational advisory.

For operators already responding to PHP2Shell, the practical task is to keep the controls and their scope straight. A version update, a startup configuration setting and a code-path review are three different observations. This guide explains how to collect them without running an exploit or treating one command-line result as proof about every website on a server.

The trigger depends on a runtime serializer change

PHP says the issue requires upload progress to remain enabled, an initial session.serialize_handler من php_binary أو php_serialize, and an application change to ص through ini_set() قبل session_start(). Applications that never change that handler at runtime are outside the described configuration. PHP plans the full advisory with its next regular release. Published prerequisites and release handling.

That is an order-of-operations question. A final runtime value of ص does not tell you whether the process started with that value or switched to it during a request. Review the startup configuration together with the code that initializes sessions. Record an unresolved call path as unknown rather than assuming the last value explains the whole request.

Initial PHP serializer and upload progress settings followed by runtime switching before session start
Published prerequisite model; not a demonstrated exploit.

Explore Penligent for authorized security testing

Why upload progress is different from ordinary application session code

إن PHP session upload progress manual describes server-side progress information stored in the session while an upload is being processed. It also explains that this information is written before application scripts execute. Consequently, moving a mitigation into a controller or middleware is not equivalent to applying a startup setting before request handling.

Disabling this feature is not the same operation as disabling all file uploads or deleting all sessions. The feature tracks progress. An application that displays an upload progress bar may depend on it, while another application may use browser-side progress or a separate upload service. Test the actual workflow rather than infer product behavior from a setting name.

The engineering lesson is to identify which layer acts first. Request parsing, session initialization and application handlers do not necessarily happen in the order suggested by the visible controller code. A code review that starts at the upload endpoint can miss configuration that was consumed earlier.

Apply the startup setting in the environment serving the request

; Apply through the startup configuration used by the web runtime.
session.upload_progress.enabled = 0

إن session configuration reference lists this directive as INI_PERDIR, with a default of enabled. Do not treat an ini_set() call in application code as a reliable way to apply it. Choose the supported configuration mechanism for the active SAPI and hosting platform, then ensure the relevant serving processes use the changed configuration.

PHP’s configuration-file documentation explains that configuration discovery depends on the runtime and that server modules read their primary file at startup. A CLI invocation may use a different configuration from the web service. Use your platform’s supported restart or redeployment process and verify the serving workers afterward; do not assume that editing a file changes every running process.

البيئةEvidence to collectCommon false conclusion
Self-managed web runtimeActive SAPI, loaded configuration, effective value and process replacement recordThe CLI says Off, so every website is covered.
Containers or multiple replicasImage or deployment identity and per-replica verificationOne replacement pod proves the rollout is finished.
Shared or managed hostingProvider confirmation for the actual site handler and effective valueA dashboard switch necessarily controls this PHP pool.
Application codeInitial serializer plus runtime changes and session-start orderThe final serializer value proves there was no transition.

Use a narrow diagnostic instead of exposing phpinfo

In a restricted staging or administrative diagnostic context, this snippet reports only the fields needed for the review. It does not call session_start(), change the serializer, read session contents or accept an upload. Run it through the same web handler as the application. Do not leave a diagnostic endpoint publicly accessible; remove it after recording the result.

<?php
header('Content-Type: application/json');
echo json_encode([
    'version' => PHP_VERSION,
    'sapi' => PHP_SAPI,
    'loaded_ini' => php_ini_loaded_file() ?: null,
    'upload_progress' => ini_get('session.upload_progress.enabled'),
    'serializer_now' => ini_get('session.serialize_handler'),
], JSON_PRETTY_PRINT);

Treat this output as a snapshot of the executing context. It does not establish whether application bootstrap code later changes the serializer, whether another pool has a different value, or whether every worker has restarted. Pair it with deployment evidence and the code review. File paths may reveal internal structure, so keep the output in the assessment record rather than a public issue.

Search for the transition, then follow the call path

From the root of an application repository you are authorized to review, these read-only searches identify relevant settings and API calls. The patterns intentionally stay simple. They will return harmless code and may miss dynamic wrappers, so use them as navigation aids rather than a vulnerability detector.

rg -n 'session\.serialize_handler|session\.upload_progress\.enabled' .
rg -n 'ini_set\s*\(|session_start\s*\(' --glob '*.php' .

For each candidate, determine which configuration is active before request processing, which bootstrap file changes the handler, and where session initialization occurs. Inspect wrappers and framework hooks when the control flow is indirect. A search hit in a test fixture is not a production finding; a setting generated outside the repository may not appear in the search at all.

Keep code evidence precise. Record the relevant file, call order, configuration owner and deployment that contains the code. Avoid posting session tokens, customer data or full environment dumps in tickets. If the application does not perform the runtime transition, document the reviewed scope rather than declaring all PHP-related risk resolved.

An offline triage model with explicit uncertainty

We executed the following Python model locally against five synthetic records. It classifies only the advisory’s configuration conditions. It sends no requests, runs no PHP and demonstrates no RCE. Unknown input remains a review item, which is useful when a hosting provider or application team has not supplied the initial configuration.

def review(enabled, initial, switches_before_start):
    if enabled is False:
        return "progress disabled"
    if enabled is None or initial is None or switches_before_start is None:
        return "review required"
    if initial in {"php_binary", "php_serialize"} and switches_before_start:
        return "matches described prerequisites"
    return "described transition absent"

cases = [
    (False, "php_binary", True),
    (True, "php_binary", True),
    (True, "php_serialize", True),
    (True, "php", False),
    (True, None, None),
]
for case in cases:
    print(review(*case))
progress disabled
matches described prerequisites
matches described prerequisites
described transition absent
review required

The labels are deliberately limited. Matching the conditions is not a successful exploitation test. An absent transition concerns this described path, not all possible session vulnerabilities. In a real review, record the source and timestamp for each input instead of turning assumptions into Boolean values.

Verify web runtime, startup setting, session initialization code and serving worker rollout
Suggested configuration verification workflow for an owned PHP application.

Explore Penligent for authorized security testing

Keep the October 21 PHP2Shell fixes in place

PHP’s October 23 notice says that operators who already disabled upload progress following the October 21 guidance should keep the setting. It does not retract the earlier security updates. PHP’s two dated notices. Do not re-enable a control simply because a package upgrade for a different CVE completed successfully.

Use separate remediation records for the earlier emergency release and this configuration review. The first should record the installed vendor-fixed package and restarted runtime; the second should record the progress setting and whether the unusual serializer transition exists. When a later regular release arrives, verify its advisory and vendor package mapping before closing the second record.

ObservationDefensible conclusion
A PHP2Shell security update was installedEvidence for the earlier update; not proof that this new setting review is complete.
Upload progress is disabled in the serving runtimeThe feature required by this described path is disabled in that checked context.
Repository search found no direct ini_set callA search result; wrappers and generated configuration may still need review.
All relevant workers and code paths were reviewedA scoped assessment record, with remaining unknowns stated explicitly.

Validate normal uploads and sessions after the change

Use benign files in your owned staging environment to exercise ordinary upload, retry and cancellation behavior. Confirm that supported uploads complete and that any progress indicator behaves as intended. Also check login persistence and session-dependent actions. A progress bar that stops updating is a functional observation, not evidence that upload processing itself is broken.

For a rollout, record the site or pool, deployment identity, effective setting, observation time and owner. If only some replicas are replaced, retain a partial status until the remaining runtime is verified. Revisit the setting after configuration-management changes so that a later deployment does not silently restore a default.

What remains unpublished as of this review

The informational notice is not a full technical advisory or an affected-and-fixed-version matrix. We therefore do not assign a CVSS score, invent a patch version or provide a command-execution payload. Recheck the official notice and your distributor’s guidance before publication or deployment decisions. This article is a configuration review guide, not a claim of confirmed exploitation in the wild.

Using an authorized security workflow

A useful assessment asks for evidence the application owner can reproduce: the correct runtime context, configuration provenance, session initialization order and post-change behavior. Evaluate automation by whether it preserves those distinctions and keeps unknowns visible. This article does not claim that Penligent has a dedicated detector for this CVE.

The following Penligent video introduces a general AI-assisted pentesting workflow. It is not a CVE-2026-115560 exploit demonstration.

Frequently asked questions

Is every PHP site exposed to this described path?

No. Review the specific startup configuration and runtime serializer transition. Do not extrapolate from the PHP version or the presence of an upload form alone.

Does disabling upload progress disable normal uploads?

It changes server-side progress tracking. Test your own application’s upload and user-interface behavior before rollout.

Can a CLI check verify the website?

It verifies the CLI context that produced the output. Confirm the actual web handler and serving configuration separately.

Should I change serializers as an emergency workaround?

Do not make an untested serializer migration in production. Session compatibility and existing data need application-specific review; follow the published startup-setting guidance.

Is the offline model an exploit test?

No. It classifies synthetic configuration records only, and does not establish exploitation or patch status.

شارك المنشور:
منشورات ذات صلة
arArabic