Nginx With PHP-FPM and PHP2Shell: What to Check
Nginx With PHP-FPM and PHP2Shell: What to Check

As of 23 October 2026, the PHP2Shell flaws are fixed in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, and nginx itself is not the vulnerable part. In an nginx setup, PHP runs in a separate service called PHP-FPM, and that is where the fix goes. Update PHP, restart PHP-FPM, and you have done the part that matters most.
Nginx still has a role. PHP's advisory names nginx as one way a PHP-FPM server can be exposed: when nginx passes PHP settings to FPM with fastcgi_param PHP_VALUE or PHP_ADMIN_VALUE and those settings produce a warning. Nginx is also where you can set request size limits that PHP recommends as an extra layer.
This page covers the nginx-side checks: those PHP_VALUE lines, keeping PHP-FPM off the network, request limits from nginx's own documentation, and the right order for restarts and reloads.
Key Takeaways
- Updating nginx does not fix PHP2Shell. Update PHP and restart PHP-FPM.
- Search your nginx configuration for PHP_VALUE and PHP_ADMIN_VALUE. Remove obsolete or invalid settings, or move them into php.ini or the FPM pool file.
- Keep PHP-FPM on a local socket or address. PHP's manual warns that anyone who can reach FPM could change its settings.
- Nginx's client_max_body_size (default 1m) and header limits help reduce exposure, but PHP says these limits do not replace updating.
- Restart PHP-FPM after the update. For nginx config changes, run nginx -t, then reload nginx.
Where the Flaw Lives in an Nginx Setup
Nginx does not run PHP code. Its beginner's guide describes how nginx can "route requests to FastCGI servers which run applications built with various frameworks and programming languages such as PHP." On most Linux servers, that FastCGI server is PHP-FPM.
PHP2Shell is two flaws in the PHP engine, CVE-2026-109618 and CVE-2026-109619. PHP lists "all PHP installations serving web requests, including PHP-FPM" as at risk. For PHP-FPM specifically, PHP's advisories say:
- CVE-2026-109618: "Source analysis therefore supports FPM as a susceptible, though no complete FPM exploit has been demonstrated for this SAPI."
- CVE-2026-109619: "Session lifecycle RCE was validated against mod_php and FPM." The advisory adds that on FPM "it depends on a suitable application operation."
So treat an nginx and PHP-FPM server as exposed until PHP is patched. Our CVE-2026-109619 summary covers the flaw behind the nginx-specific checks below, at advisory level.
Step 1: Patch PHP-FPM and Restart It
Install the fixed PHP release or your distribution's patched package, then restart PHP-FPM. On Ubuntu and Debian the service is named after the version:
sudo systemctl restart php8.3-fpm (replace 8.3 with your version)
On AlmaLinux, RHEL and Fedora it is sudo systemctl restart php-fpm. If the server runs several PHP versions, restart each one that serves a site. Commands for every setup, and how to confirm the restart, are in our guide to restarting PHP workers. FPM pool settings and FPM-specific details are in our PHP-FPM guide.
Step 2: Audit fastcgi_param PHP_VALUE and PHP_ADMIN_VALUE
Nginx documents its fastcgi_param directive in one line: "Sets a parameter that should be passed to the FastCGI server." PHP-FPM accepts two special parameters, PHP_VALUE and PHP_ADMIN_VALUE, that change PHP settings per request. The PHP-FPM configuration manual shows them in an nginx example.
PHP's advisory for CVE-2026-109619 says FPM "is conditionally exposed when nginx, Apache mod_proxy_fcgi or another frontend sends PHP_VALUE / PHP_ADMIN_VALUE parameters that produce a diagnostic before request initialization." A diagnostic here means any warning, notice or deprecation message, even one that is never shown or logged.
The advisory's remediation: "Eliminate diagnostics from all INI configuration applied before request initialization. Prefer php.ini, FPM pool or server configuration applied at startup over per request overrides, and remove obsolete directives."
How to check:
- Dump the full nginx configuration and search it. Nginx documents nginx -T as "same as -t, but additionally dump configuration files to standard output." For example: sudo nginx -T | grep -n -E "PHP_VALUE|PHP_ADMIN_VALUE"
- For each setting you find, ask whether it is still needed and still valid for your PHP version. PHP's interim guidance names "invalid or deprecated settings applied per request" as the ones to remove.
- Delete the ones you don't need. Move the rest into php.ini or the FPM pool file, using php_admin_value[...] in the pool where applications should not override them.
- Restart PHP-FPM if you changed pool files, then test and reload nginx (Step 5).
Hiding the warnings is not a fix. PHP's advisory says changing error_reporting, using @, or turning off display_errors or log_errors "does not protect against this vulnerability." The same audit applies to Apache servers that pass settings with mod_proxy_fcgi.
Step 3: Keep PHP-FPM Off the Network
PHP_VALUE is powerful because whoever can talk to PHP-FPM can use it. The PHP-FPM manual's caution is direct: "Because these settings are passed to php-fpm as fastcgi headers, php-fpm should not be bound to a worldwide accessible address. Otherwise, anyone could alter the PHP configuration options."
Check the listen line in each FPM pool file. A Unix socket or a local address keeps FPM reachable only from the same machine. If nginx and FPM run on different machines, the manual points to listen.allowed_clients to limit which addresses may connect, and a firewall rule should do the same. This belongs on any website security checklist, PHP2Shell or not.
Step 4: Request Limits at Nginx
For CVE-2026-109618, PHP's advisory suggests "enforcing limits at the web server or proxy level for decoded request size, input field count, multipart part count, header count, and nesting depth. These limits must also cover requests without a usable Content-Length." The advisory also says these controls "reduce hard OOM and denial of service risk even after applying the patch, but do not replace updating."
These are the nginx directives that set request limits, as documented in nginx's core HTTP module on 23 October 2026:
| Directive | Default | What nginx's documentation says it does |
|---|---|---|
| client_max_body_size | 1m | "Sets the maximum allowed size of the client request body." Larger requests get a 413 error. A value of 0 turns the check off. |
| large_client_header_buffers | 4 8k | Sets the number and size of buffers for large request headers. A header field larger than one buffer gets a 400 error. |
| client_header_buffer_size | 1k | The first buffer for reading request headers; larger ones fall back to large_client_header_buffers. |
| max_headers | 1000 | "Sets the maximum allowed number of header lines in requests." Added in nginx 1.29.8, so older builds don't have it. |
| client_body_timeout and client_header_timeout | 60s | End a request with a 408 error if the client stops sending. |
Practical points:
- Check for client_max_body_size 0. Some configurations turn the size check off to allow big uploads. Set a real limit that fits your largest legitimate upload.
- Line it up with PHP. PHP's interim advice is post_max_size = 8M for sites without uploads and 32M for sites with them. A nginx limit that matches your PHP setting stops oversized requests before PHP sees them.
- Know the gaps. Nginx's core module has no directive that counts form fields, multipart parts or nesting depth. Those limits are PHP settings, covered in our interim mitigations guide, or WAF rules.
- Test the edge case. Nginx's documentation describes client_max_body_size as a limit on the request body but does not spell out how it treats bodies sent without a Content-Length header. Since PHP says limits must cover those requests, confirm with whoever maintains your setup.
Test upload forms and large form posts after any change. A limit set too low breaks them, and nginx notes that "browsers cannot correctly display" its 413 error, so users may see a blank failure.
PHP's advisory also says: "If the application does not use multipart form data, block such requests at the frontend before they reach PHP." Multipart is the format browsers use for file uploads, so this only suits sites with no upload forms. Ask your developer or WAF provider how to do it without breaking other forms.
Step 5: Restart and Reload in the Right Order
- Update PHP and restart PHP-FPM first. This is the fix. Nginx does not need a restart for it.
- Make your nginx changes, such as removed PHP_VALUE lines or new limits.
- Test the configuration: sudo nginx -t. Nginx documents it as a check of the configuration "for correct syntax."
- Reload nginx: sudo nginx -s reload. Per nginx's documentation, a reload starts new worker processes with the new configuration and gracefully shuts down the old ones. If the new configuration fails, nginx "rolls back changes and continues to work with old configuration."
- Restart PHP-FPM again if you moved settings into php.ini or a pool file in step 2.
A full nginx restart (sudo systemctl restart nginx, as Ubuntu documents) also works, but a reload is enough for configuration changes, and it lets old workers finish serving current clients.
Nginx in Front of Apache
Some servers, including many control panel setups, use nginx as a front end that passes requests to Apache. In that case, check how Apache runs PHP. If it uses mod_php, the PHP risk sits inside Apache, which PHP calls the highest-risk setup. Restart Apache after the update; see our Apache mod_php guide. The nginx request limits above are core settings, so they apply to requests nginx passes to Apache as well.
Nginx and PHP-FPM Checklist
| Check | Done when |
|---|---|
| PHP updated | Every PHP version serving a site is on a fixed release or patched package |
| PHP-FPM restarted | Each FPM service shows a start time after the update |
| PHP_VALUE and PHP_ADMIN_VALUE | nginx -T shows none, or only settings you have confirmed produce no warnings |
| FPM listen address | Unix socket or local address, or restricted with listen.allowed_clients and a firewall |
| client_max_body_size | Set (not 0) and in line with post_max_size |
| Config tested and reloaded | nginx -t passes, nginx reloaded, uploads tested |
Conclusion
With nginx and PHP-FPM, the fix lives in PHP: update it and restart PHP-FPM. Then use nginx to close the gaps PHP's advisory points at: remove risky PHP_VALUE lines, keep FPM off the network, and set request limits that fit your site. Confirm your PHP build with our guide on how to check your PHP version, and make the restart part of your routine with our security patching guide. If you want a team to patch and review your nginx servers, our emergency PHP patching service can help. Every PHP2Shell guide is in our PHP2Shell Resource Center.
Frequently Asked Questions
Is nginx vulnerable to PHP2Shell?
No. PHP2Shell is a flaw in the PHP engine. Nginx passes requests to PHP-FPM, and PHP-FPM is what needs the update.
Do I need to update nginx?
Not for PHP2Shell. Keep nginx current for its own security fixes, but an nginx update does not change PHP.
Do I need to restart nginx after patching PHP?
No. Restart PHP-FPM. Reload nginx only if you changed its configuration.
Does client_max_body_size protect me from PHP2Shell?
It helps reduce exposure to oversized requests, but PHP says frontend limits "do not replace updating." Patch PHP first.
Can I put session.upload_progress.enabled=0 in a fastcgi_param PHP_VALUE line?
PHP's advice is to set interim settings in php.ini, the FPM pool or server configuration that applies before request parsing, and to prefer startup configuration over per-request overrides. The pool file or php.ini is the safer place.
What is the difference between nginx reload and restart?
A reload applies new configuration by starting new worker processes and letting old ones finish their requests. A restart stops and starts the whole service. Both pick up configuration changes; neither restarts PHP-FPM.
Put this into action with eSEOspace
We help businesses grow with maintenance & support that actually performs. Explore the services behind this guide:
Get a FREE Audit
We'll perform a comprehensive SEO, AEO, GEO & CRO audit of your website — completely free — and show you exactly how to outrank your competitors.
Don't have a site yet? Get in touch →
Get a FREE GEO/AEO/SEO Audit
We'll analyze your site's SEO, GEO, AEO & CRO — completely free — and show you exactly how to get found across Google and AI answers.
Don't have a site yet? Get in touch →
Great — your audit is on the way!
We'll send your free SEO/GEO/AEO/CRO audit within the next few hours. Where should we send it?
You're all set! ✓
Your free audit is being prepared — check your inbox in the next few hours. Talk soon!
On this page
- Key Takeaways
- Where the Flaw Lives in an Nginx Setup
- Step 1: Patch PHP-FPM and Restart It
- Step 2: Audit fastcgi_param PHP_VALUE and PHP_ADMIN_VALUE
- Step 3: Keep PHP-FPM Off the Network
- Step 4: Request Limits at Nginx
- Step 5: Restart and Reload in the Right Order
- Nginx in Front of Apache
- Nginx and PHP-FPM Checklist
- Conclusion
- Frequently Asked Questions





