In short: After PHP2Shell, Drupal PHP security is mainly about the server: the flaw is in PHP, not in Drupal. Check the PHP status in the status report and with your operator, restart all PHP processes, and then inspect settings.php, the files directory and the role permissions.
Drupal and PHP2Shell: the situation
Drupal is often used for larger websites, portals and public bodies, frequently with many editors and interfaces. According to the PHP team, the PHP flaws CVE-2026-109618 and CVE-2026-109619 allow remote code execution without authentication. How well Drupal itself is maintained plays no role here.
Drupal has its own security team, which publishes advisories for core and modules. PHP2Shell is not among them, because it is not a Drupal flaw. Anyone who only follows the Drupal advisories may therefore have missed the report.
In larger Drupal projects, responsibility is often spread across several parties: an agency maintains the code, a data centre operates the servers, the editorial team sits in-house. Clarify in writing who applies the PHP update, who triggers the restart and who checks whether anything happened beforehand. In setups with several web servers behind a load balancer, every single server must be patched and restarted, otherwise part of the requests stays on old PHP.
Drupal PHP security: checking the version and patch level
Under Reports > Status report, Drupal shows the PHP version the website is running on, together with configuration warnings. On the command line, drush status returns the version of the CLI PHP, which cron jobs and deployments also run on. Both must be patched.
Fixed upstream versions are 8.5.12, 8.4.27, 8.3.36 and 8.2.35. Distributions and hosts sometimes apply fixes as a backport, in which case the number stays the same; the confirmed package status is what counts. Which PHP versions your Drupal version supports can be found in the system requirements on drupal.org. After the update, the restart is part of the job, as described under Restarting PHP-FPM and all workers.
Directories and files that matter
| Location | Content | What to check |
|---|---|---|
sites/default/settings.php |
Database, hash salt, trusted_host_patterns |
Modification date, inserted includes |
sites/default/files/ |
Public uploads, generated images, CSS and JS | No PHP files, .htaccess present |
| Private file directory | Protected uploads, often outside the document root | Access permissions |
modules/contrib/, modules/custom/ |
Modules from drupal.org and custom developments | Modified or unknown modules |
themes/ |
Themes with Twig templates | Foreign JavaScript |
vendor/ |
Composer dependencies | composer audit |
Drupal creates an .htaccess in the files directory that prevents the execution of PHP. Under Apache it works, under Nginx it does not. There, a rule of your own is needed:
location ~* ^/sites/.+/files/.+\.php$ {
deny all;
}
Harmless checks with built-in tools and Drush:
find sites/*/files -type f -name "*.php"
drush pm:list --status=enabled --type=module
composer audit
Compare the code on the server with your Git repository. In Drupal projects using Composer, this is the quickest way to find foreign or modified files, because every deviation must be explainable.
Roles, permissions and modules as a risk
The login is at /user/login, the administration area at /admin. In Drupal, security is decided not only by administrator accounts but by individual permissions. Permissions such as administering modules, users, permissions or text formats with full HTML are practically administrator rights. Under People and Permissions, check which roles have them and who belongs to those roles.
Contrib modules extend Drupal considerably but bring their own code. Modules without active maintenance and old custom developments are often the reason a PHP upgrade is postponed. More on dependencies can be found under Checking Composer dependencies for vulnerabilities.
What a Drupal update achieves and what it does not
A core or module update closes flaws in that code and can enable newer PHP versions. It does not patch PHP, does not remove foreign files from sites/default/files, does not reset permissions and does not delete secretly created accounts. The cache can also keep delivering manipulated content until it is cleared. After a suspicion, the hash salt and database credentials should be renewed.
In multisite installations, several websites share the same code but each has its own settings.php and its own files directory under sites/. Check each website individually then. Because of the shared code, a finding in one site usually affects all the others as well.
How does PHP SOS help?
- We check the web and CLI PHP of your Drupal server and have the patch and restart confirmed.
- We secure logs and data and compare the code with your repository or the original packages.
- We check
settings.php, thefilesdirectory, server rules, roles and permissions. - On request, we take over ongoing maintenance in the security maintenance contract, so that PHP and Drupal updates do not drift apart again.
Frequently asked questions
Does a Drupal security update help against PHP2Shell?
No. Drupal updates close flaws in Drupal core and modules. PHP2Shell sits in the server's PHP and needs a PHP update or a confirmed backport, plus a restart of all PHP processes.
Where does Drupal show the PHP version?
In the status report under Reports. With Drush, drush status shows the command-line PHP version. The two can differ, and neither reliably reveals a backport.
Does the .htaccess in the files folder also protect under Nginx?
No. The .htaccess created by Drupal is only evaluated by Apache. Under Nginx you need your own rule in the server configuration that blocks PHP files in the files directory.
What does trusted_host_patterns mean?
The setting in settings.php defines under which host names Drupal responds. It protects against attacks via manipulated host headers and belongs in every production installation.