Skip to content

fix: disable session.upload_progress for new and existing sites - #120

Merged
mrrobot47 merged 4 commits into
EasyEngine:developfrom
mrrobot47:fix/disable-session-upload-progress
Oct 21, 2026
Merged

mrrobot47 merged 4 commits into
EasyEngine:developfrom
mrrobot47:fix/disable-session-upload-progress

Conversation

@mrrobot47

@mrrobot47 mrrobot47 commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

PHP's 2026-10-21 security advisory for CVE-2026-109618 (GHSA-w8hw-w9fx-j79w) and CVE-2026-109619 (GHSA-6wmf-4rv5-p3rp), announced at https://www.php.net/archive/2026.php#2026-10-21-1, names session upload progress as an attack path: "Session lifecycle RCE was validated against mod_php and FPM". The official mitigation is: "Set session.upload_progress.enabled=0 and restart every worker. Use php.ini, an FPM pool or server configuration that applies before request parsing. Do not rely on ini_set() or FPM .user.ini." PHP also recommends keeping it off after patching if it isn't used.

This PR applies that mitigation to every PHP site. It is defence in depth, not a substitute for the patched PHP images (8.2.35, 8.3.36, 8.4.27 and 8.5.12). An application that reports upload progress through PHP sessions needs it turned back on (see the end of this description). PHP 8.1 and older get no official release with the fix, so for sites still on those versions this setting is the main protection until they move to a supported version.

The setting goes into each site's custom.ini, which php-fpm loads from its scanned conf.d at startup, before any request is parsed. Running sites then get a graceful php-fpm reload (kill -USR2 1, as ee site reload does), which re-executes the master and replaces every worker.

New sites: php.ini.mustache and php.ini-56.mustache set it to Off. Note that PHP.php reads custom.ini from site-type-wp's templates (SITE_WP_TEMPLATE_ROOT), so new PHP sites get the setting from the matching site-type-wp change; these two templates are updated to keep the copies identical.

Existing sites: container migration 20261021120100_site-type-php_disable_php_session_upload_progress.php adds the setting to config/php/php/conf.d/custom.ini of every PHP site, enabled or disabled, on every PHP version. It is the same code as site-type-wp's migration with its own class name (DisablePhpSessionUploadProgress), since all migrations share one namespace:

  • A file that already sets session.upload_progress.enabled globally (On or Off) is left alone. The check uses PHP's own ini parser in the same mode as php.ini, and only entries before the first section whose name starts with PATH or HOST count, since PHP scopes everything after such a header to it (even under later ordinary headers). So a commented-out line, a wrong-case key or a value set only in a scoped section doesn't count, and a scoped override is kept as it is; for a file with a syntax error, only the lines above it count, as in PHP.
  • The file is edited in place, so owner, mode and inode stay the same (macOS bind-mounts the single file). CRLF line endings and a UTF-8 BOM are kept, and the rest of the file is unchanged. The setting goes at the very top, so neither a [PATH=]/[HOST=] section nor a multi-line quoted value can capture it. A missing custom.ini is recreated with the owner of its conf.d. A symlinked custom.ini or a directory in its place is skipped with a warning.
  • The original files are kept in /opt/easyengine/.backup/session-upload-progress-php-<timestamp>/<site>/custom.ini. If a later step of the upgrade fails, down() restores them byte for byte and reloads php-fpm of the running sites.
  • Running sites get the same graceful php-fpm reload as ee site reload (kill -USR2 1) once the image migration is done, except those whose php container the image migration recreated. Disabled sites pick it up when they're enabled.
  • A problem with one site (including a failed docker-compose ps when looking up its php container) is a warning that names the site and the manual fix, so it doesn't block the upgrade.

To undo it on a site, remove the line from custom.ini (or set it to On), then run ee site reload <site>.

On macOS, custom.ini is currently bind-mounted outside the conf.d directory PHP scans (a separate, older issue), so the setting has no effect there yet; that needs its own fix.

Testing: same matrix and live upgrade as the site-type-wp PR; the live run had PHP sites on 8.1, 5.6 and 8.4 (one disabled, one with extra user settings), checked through FPM, with multipart uploads before and after.

Needs a core release that pins this tag together with site-type-wp's matching change.

The session upload progress handler is not needed by WordPress or most apps; turning it off removes it as an attack surface (php2shell hardening). Apps that need it can set it back to On in custom.ini.
Adds session.upload_progress.enabled = Off to the custom.ini of every php site, enabled or disabled, unless it already sets it. Files are edited in place (owner, mode and inode kept), originals are backed up under EE_BACKUP_DIR and restored if the upgrade rolls back. Running sites get a graceful php-fpm reload after the image migration, skipped for php containers it recreated; disabled sites pick it up when enabled. Per-site problems are warnings so they don't block the upgrade.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Unresolved migration issues and security-sensitive reload and rollback dependencies on companion core changes require fixes and human integration review.

2 open issues
What changed in this PR

Disables PHP session upload progress by default as security hardening for new and existing PHP sites.

Changes:

  • Updates both PHP INI templates.
  • Adds an existing-site migration with backups, rollback, and deferred FPM reloads.
File Description
templates/​config/​php-fpm/​php.ini.mustache Disables session upload progress by default.
templates/​config/​php-fpm/​php.ini-56.mustache Applies the same default for PHP 5.6.
migrations/​container/​20261021120100_site-type-php_disable_php_session_upload_progress.php Updates existing configurations and manages backups and reloads.

Review effort: Balanced

…ns set it

custom.ini is now read with PHP's own ini parser (same mode as php.ini) to find a global session.upload_progress.enabled, so a value set only inside a [PATH=] or [HOST=] section no longer counts. The new lines go at the very top of the file, where neither such a section nor a multi-line quoted value can capture them; for a file with a syntax error only the lines above it count, matching what PHP applies. A failed docker-compose ps is now a warning with the reload command instead of being treated as a stopped container.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Scoped INI headers containing whitespace can cause the migration to skip the global security mitigation.

1 open issue
2 resolved since last review

Review effort: Balanced

PHP treats any section whose name starts with PATH or HOST (case-insensitive, spaces allowed before the =) as scoped, and entries under a later ordinary header stay in that scope. Only the part before the first such header now counts as global, so a scoped-only setting no longer stops the global Off from being added.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Scoped-header detection can incorrectly skip sites that still need the global security mitigation.

1 open issue
1 resolved since last review

Review effort: Balanced

@mrrobot47
mrrobot47 merged commit a1f5db5 into EasyEngine:develop Oct 21, 2026
2 checks passed
@mrrobot47
mrrobot47 deleted the fix/disable-session-upload-progress branch October 21, 2026 15:19
mrrobot47 added a commit to EasyEngine/easyengine that referenced this pull request Oct 21, 2026
Switches off session.upload_progress for new sites and, through a container migration, for every existing WordPress and PHP site on all PHP versions (EasyEngine/site-type-wp#246, EasyEngine/site-type-php#120).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants