PHP2Shell and Symfony: What Developers Need to Do

By: Irina Shvaya | October 23, 2026
This guide is part of our PHP2Shell Resource Center: fixed versions, how to check your PHP version, WordPress, Drupal and Joomla steps, mitigations and signs of a hack.

As of 23 October 2026, PHP has fixed both PHP2Shell flaws in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. We found no PHP2Shell statement on the Symfony blog as of that date. Exploitation attempts are widely reported, but confirmed successful compromises are not publicly documented, and CISA has not added the flaws to its Known Exploited Vulnerabilities (KEV) catalog.

The direct answer: PHP2Shell (CVE-2026-109618 and CVE-2026-109619) is a flaw in the PHP engine, not in Symfony. Researchers at Calif confirmed that it could be used against Symfony 8.1, but the weakness sits below your code, in how PHP handles requests. Updating Symfony or running composer update does not fix it. A fixed PHP build on every server or image does, followed by a restart of every PHP process, including Messenger workers.

This guide covers which PHP each maintained Symfony branch needs, the special case of Symfony 6.4 LTS on PHP 8.1, Docker setups built on FrankenPHP, and long-running workers. For background, read what PHP2Shell is.

Key Takeaways

  • Calif lists "Symfony 8.1" among the apps where it confirmed unauthenticated remote code execution. The bug is in PHP, so no Symfony release fixes it.
  • Symfony 8.1 needs PHP 8.4 or newer, Symfony 7.4 LTS needs PHP 8.2 or newer, and Symfony 6.4 LTS allows PHP 8.1, which gets no official PHP2Shell release.
  • Apps built from the Symfony Docker template run on FrankenPHP, which builds PHP into its image. Rebuild with a fresh pull, then recreate the containers.
  • Messenger workers keep the old PHP in memory until they exit. Stop them after patching and let your process manager start new ones.
  • The Symfony CLI's local web server is a development tool. Patch the PHP on your laptop too, but production servers come first.

Is Symfony Affected by PHP2Shell?

Yes, through PHP. PHP describes the two flaws this way. CVE-2026-109618: out-of-memory handling "can interrupt PHP while internal request data is only partially initialized." CVE-2026-109619: request-owned internal state "can survive after its backing memory has been freed," so that a later request on the same worker may use it. Both happen in PHP's own request startup and cleanup, before or around your Symfony kernel.

Calif's write-up lists Symfony 8.1 among 11 PHP apps where it "confirmed pre-auth RCE," meaning it could run code on the server without logging in. Wiz, the other main research team, demonstrated attacks only against WordPress, Drupal and Joomla. Neither team named an older Symfony branch, but that is not a sign of safety. The flaw is in PHP, so any Symfony version on an unpatched PHP build is exposed.

The Dutch National Cyber Security Centre (NCSC-NL) keeps a public list of affected software. It marks the "Symfony framework" as Vulnerable and individual components such as HttpFoundation and HttpKernel as under investigation. The list itself warns that its entries "should still be treated as investigation leads until they are backed by an upstream or vendor source."

We checked the Symfony blog on 23 October 2026 and found no PHP2Shell post. If Symfony publishes guidance later, follow it.

Symfony Branches and the PHP They Need

From the Symfony releases page, as shown on 23 October 2026:

Symfony branchRequiresSupportPHP2Shell note
8.1 (current stable)PHP 8.4.0 or higherEnd of support January 2027Use PHP 8.4.27 or 8.5.12 or later
7.4 LTSPHP 8.2.0 or higherBug fixes to November 2028, security fixes to November 2029Use 8.2.35, 8.3.36, 8.4.27 or 8.5.12 or later; 8.3 or newer is safer long term
6.4 LTSPHP 8.1.0 or higherBug fixes to November 2026, security fixes to November 2027On PHP 8.1 there is no official PHP release; move to 8.2 or newer
8.0PHP 8.4.0 or higherEnded July 2026Unmaintained; upgrade to 8.1
8.2 (due November 2026)PHP 8.4.0 or higherEnd of support July 2027Not yet released

Symfony 7.3 and older are unmaintained. If you run one of those, patch PHP now and plan the framework upgrade separately. Don't combine a rushed framework upgrade with an emergency PHP fix if you can avoid it.

Symfony 6.4 LTS on PHP 8.1: The Gap to Close

Symfony 6.4 is still a maintained long-term support branch, and it runs on PHP 8.1. PHP 8.1 reached end of life on 31 December 2025. PHP's 21 October announcement says "PHP 8.1 and older no longer receive updates from the PHP project. Some distributions and LTS vendors provide backported fixes."

So a 6.4 app on PHP 8.1 is only safe if the PHP build under it carries a backport, for example from your Linux distribution's security updates. PHP also published minimal source-only backports for 7.4, 8.0 and 8.1 for people who build PHP themselves, but there are no official 8.1 releases or binaries. The official Docker php:8.1 image had not been rebuilt as of 23 October.

The practical route for most teams: move the 6.4 app to PHP 8.2 or newer, which Symfony 6.4 accepts. PHP 8.2 itself ends on 31 December 2026, so 8.3 or 8.4 buys more time. Test on staging first, because a PHP version jump can surface deprecation warnings and behavior changes in your own code. Our PHP 8.1 guide covers the backport options.

Who Patches PHP Under Your Symfony App

Symfony is a framework, so there is no vendor cloud that patches it for you by default. Who updates PHP depends on hosting:

  • Your own VPS or dedicated server: you. Install the distribution's fixed PHP packages and restart PHP-FPM or Apache.
  • Containers you build: you. Rebuild every image from a fixed base and redeploy. Google Cloud puts it plainly: "Container images you build yourself are your responsibility."
  • A platform-as-a-service: usually the platform, for its built-in runtimes, but check. Some platforms patch in place and others need a redeploy.
  • A managed agency or host: ask them in writing which PHP build now serves the app and when workers were restarted.

Our shared responsibility guide explains how to work out who owns which layer.

Symfony Docker and FrankenPHP

Many newer Symfony projects start from the Symfony Docker template, which its README describes as a runtime "with FrankenPHP and Caddy inside," using "the worker mode of FrankenPHP." FrankenPHP compiles PHP into its binary and images. You can't update PHP inside it with a package manager. You need a FrankenPHP image built with fixed PHP.

  1. Check your Dockerfile's base image. The current template starts from dunglas/frankenphp:1-php8.5, a floating tag. Your project's copy may differ, depending on when it was created.
  2. Rebuild with a fresh pull. The template's own instructions use docker compose build --pull --no-cache, which fetches the newest base image instead of a cached one.
  3. Recreate the containers. Pulling or building alone leaves the old container running. docker compose up -d (or your orchestrator's rollout) replaces containers whose image changed.
  4. Consider pinning. A tag naming both versions makes the PHP inside obvious. FrankenPHP 1.13.2 was the first release built with fixed PHP.

Restarting FrankenPHP workers through its admin API re-runs your app inside the same process, with the same built-in PHP. That's useful for new code, not new PHP. Our FrankenPHP guide covers every install method.

Messenger Workers and Other Long-Running Processes

A PHP process that is already running keeps the PHP it started with. In a Symfony app, the usual long-running processes are Messenger consumers (messenger:consume), FrankenPHP or other worker-mode runtimes, and any custom daemon commands.

The Messenger documentation describes php bin/console messenger:stop-workers: it "sets a cache flag that tells each worker to finish its current message and exit cleanly. The process manager then restarts them." After a PHP update, the new workers start on the new PHP. Two things to check:

  • The docs note that if your app "runs on multiple hosts," the app cache must use a shared adapter so the stop signal reaches every worker.
  • Make sure something restarts the workers: Supervisor, systemd or your container platform. Then confirm their start times are after the update.

For PHP-FPM, use a full restart rather than relying on a reload. Our guide to restarting PHP workers has the exact commands for each Linux distribution, Apache and containers.

Step by Step: What to Do Today

  1. List every environment. Production, staging, preview and demo servers, plus any old instances still in DNS. Staging on a public URL is as reachable as production.
  2. Find the PHP that serves each one. The command-line php -v can differ from the web server's PHP, so check what PHP-FPM or the container actually runs. Our PHP version guide explains the reliable ways.
  3. Update or rebuild. Fixed releases are 8.5.12, 8.4.27, 8.3.36 and 8.2.35. On distribution builds, confirm the fix in the package changelog, because backported packages keep their old version numbers.
  4. Restart everything that runs PHP. PHP-FPM or Apache, Messenger workers, FrankenPHP processes and containers.
  5. Verify. Recheck the serving PHP version or build, and confirm process start times.
  6. Review logs from 17 October onward. Look for unusual multipart requests, memory-exhaustion errors and worker crashes.

What Updating Symfony or Composer Does Not Do

Keeping Symfony and its packages current matters for Symfony's own security fixes. It does nothing for PHP2Shell. A few related traps:

  • Framework-level request limits run after PHP has already parsed the request, so they can't block a flaw in PHP's own parsing.
  • Interim settings belong in php.ini or the FPM pool, not in ini_set() calls or .user.ini files, which PHP says don't work for these mitigations. PHP also says to remove invalid or deprecated per-request settings that produce warnings before a request starts. Our interim mitigations guide covers each setting.
  • Your local machine is not production. The Symfony CLI docs say its local web server "is not intended for production use." Update your laptop's PHP when you can, but don't treat that as part of the server fix.

Keep session.upload_progress.enabled=0 after patching too, if you don't use PHP's built-in upload progress. PHP's 23 October advisory on a related issue, CVE-2026-115560, recommends it until the next regular PHP release.

Conclusion

For Symfony teams, PHP2Shell is a runtime job. Put every environment on a fixed PHP build, move Symfony 6.4 apps off PHP 8.1, rebuild FrankenPHP-based images with a fresh pull, and stop Messenger workers so they come back on the new PHP. Then verify the version the web server actually runs. Your Docker base images and Composer packages are part of your supply chain, so track their versions the way our supply chain security guide describes. If you'd like help patching and verifying several environments at once, our emergency PHP patching service can step in. Every PHP2Shell guide is in our PHP2Shell Resource Center.

Frequently Asked Questions

Has Symfony released a patch for PHP2Shell?

No Symfony patch is needed, because the flaw is in PHP. We found no PHP2Shell post on the Symfony blog as of 23 October 2026. The fix is a patched PHP build plus a restart.

Which Symfony versions did researchers test?

Calif lists Symfony 8.1 as confirmed. That doesn't make other versions safe. Any Symfony app on unpatched PHP is exposed, whatever its version.

Can Symfony 6.4 stay on PHP 8.1?

Only on a PHP build that carries a backported fix, such as a distribution security package. PHP itself ships no 8.1 release. Moving to PHP 8.2 or newer, which 6.4 supports, is the cleaner fix.

Does messenger:stop-workers apply the PHP fix?

Only once the new PHP is installed. The command makes workers exit cleanly. Your process manager then starts new ones, and those load the updated PHP.

I use the Symfony Docker template. What do I rebuild?

Your app image. Rebuild with docker compose build --pull --no-cache so it uses a FrankenPHP base built with fixed PHP, then recreate the containers.

Does a web application firewall replace patching?

No. A firewall can block known attack patterns, but PHP says only an update is a complete fix. A firewall also doesn't help if attackers can reach the server directly by its IP address.

Put this into action with eSEOspace

We help businesses grow with maintenance & support that actually performs. Explore the services behind this guide:

Book a free strategy call →

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 →

You Might Also like to Read