Opened 6 months ago
Last modified 6 months ago
#63882 new defect (bug)
Plugins: Preflight activation to avoid WSOD when plugin code uses syntax incompatible with PHP runtime
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Awaiting Review | Priority: | normal |
| Severity: | major | Version: | 6.8.2 |
| Component: | Plugins | Keywords: | has-patch needs-testing |
| Focuses: | sustainability, php-compatibility | Cc: |
Description
Problem
Activating a plugin whose code is valid only on newer PHP versions (for example, using false as a return type in PHP 8.3) on a site running an older PHP version (e.g. PHP 8.0) can produce a fatal parse error. Because the plugin can already be persisted as "active" before compatibility is verified, the site can end up in a broken/white-screen state that requires DB or filesystem access to recover.
Steps to reproduce
- On a site running PHP 8.0, install a plugin whose main file uses syntax valid in PHP 8.3 (e.g.,
function foo(): false {}). - Attempt to activate the plugin via wp-admin → Plugins → Activate.
- The site will display a fatal parse error and the plugin will be in the active_plugins list, causing further loads to attempt to include it.
Expected
Plugin activation should perform a preflight check and not persist a plugin as active if its main file produces a fatal/parsing error. A failed activation should abort and leave the active_plugins option unchanged.
Proposed solution
Before updating active_plugins, preflight-load the plugin main file (sandboxed). If loading produces a fatal error (parse or otherwise), abort activation and show the error without saving the plugin as active. Implementation changes are proposed in:
src/wp-admin/includes/plugin.php(insideactivate_plugin())- Unit tests added in
tests/phpunit/tests/admin/includesPlugin.php
Patch/PR
A PR is available on GitHub and this ticket will include the patch. Please see linked PR for details.
Environment tested
- WordPress: <trunk>
- PHP: 8.3 (plugin syntax that causes repro)
- OS: Windows 11
- Browser: Google Chrome
Change History (2)
This ticket was mentioned in PR #9611 on WordPress/wordpress-develop by @codad5.
6 months ago
#1
- Keywords has-unit-tests added
#2
@
6 months ago
- Keywords has-unit-tests removed
Hi! 👋
I’ve submitted a corresponding GitHub pull request for this patch:
👉 https://github.com/WordPress/wordpress-develop/pull/9611
The PR contains the code changes in src/wp-admin/includes/plugin.php along with unit tests.
Feedback and review would be much appreciated! 🙏
Props: codad5
Trac ticket: https://core.trac.wordpress.org/ticket/63882
### Summary
Prevents sites from entering a fatal error (WSOD) when activating a plugin that uses PHP syntax incompatible with the current runtime. Before persisting the plugin as active, a preflight check safely includes the plugin file. If a parse error or exception occurs, activation is aborted and the error is displayed without saving the plugin to the database.
### Technical Changes
safe_plugin_activation_check()inplugin.phpto sandbox plugin file loading, converting errors/exceptions intoWP_Error.activate_plugin()to callsafe_plugin_activation_check()before persisting the plugin.WP_Errorif activation would trigger a fatal error.### Tests
tests/phpunit/tests/admin/includesPlugin.php.### Notes