FrankenPHP 1.13.2 is a security release. Its Docker images and static binaries are built with the PHP versions that fix PHP2Shell (CVE-2026-109618 and CVE-2026-109619), two critical vulnerabilities allowing unauthenticated remote code execution. It also fixes 4 vulnerabilities in FrankenPHP itself, including a high-severity one that let a local user get their PHP code executed by a service running an embedded app. It also makes frankenphp_log() available in php-cli, stops hot reload from serving stale pages, and moves static builds to static-php-cli v3. Static builds have a few changes worth reading in the upgrade notes below. Upgrading is strongly recommended.
🔒 Security
- Critical, PHP2Shell: Docker images are built with PHP 8.2.35, 8.3.36, 8.4.27 and 8.5.12, and static binaries with PHP 8.5.12. These versions fix CVE-2026-109618 and CVE-2026-109619, which allow unauthenticated remote code execution and have no complete mitigation besides upgrading (PHP security advisory).
- High: Embedded apps were extracted to a predictable directory in the shared temp dir, and existing files were reused. A local user could precreate that directory and get their PHP code executed by the service. Apps are now extracted atomically to a per-user directory, which is only reused when the current user owns it (GHSA-6q3j-62j9-f9hh).
- Requests waiting for a PHP thread are now dropped when their client disconnects. Before this fix, an unauthenticated client could queue requests, disconnect and keep the thread pool busy for everyone else (GHSA-fq24-r53r-xcx3).
- Cyclic arrays are now rejected when PHP values are converted to Go. A self-referencing array passed to
frankenphp_log(), returned by a worker callback or given to the extension API overflowed the stack and crashed the whole process (GHSA-ccgp-ch9h-533f). - Worker mode: The errors returned by
error_get_last()andlibxml_get_errors()are now cleared at the end of each request. Before this fix, they could leak fragments of a previous client's input and server paths into the next request served by the same thread (GHSA-4gfw-9v29-gp9h).
⚠️ Upgrade Notes
Static builds now use static-php-cli v3 by @henderkes in #2618:
- macOS: Binaries are only published for Apple Silicon. There is no
frankenphp-mac-x86_64asset anymore. On Intel Macs, build from source withbuild-static.sh. - glibc builds: The
-gnubinary now requires glibc 2.28 or later, instead of 2.17. - Static builder images: Run them with
docker runand passPHP_EXTENSIONS,PHP_EXTENSION_LIBS,XCADDY_ARGSand the other options as environment variables instead of Docker build args. The binary is written to the mounted/outputdirectory, and the defaults now live incraft.yml. See the static build docs.
✨ New Features
- CLI:
frankenphp_log()and theFRANKENPHP_LOG_LEVEL_*constants are now available inphp-cli, so code shared between web requests and commands can log the same way. Entries use the server's format and are written to stderr. TheCaddyfileisn't loaded, so itslogdirectives don't apply by @dunglas in #2719. - Extensions:
frankenphp_thread_index()is exported again for C extensions such as frankenstate and frankenasync by @nickchomey in #2717.
🐛 Bug Fixes
- Hot reload:
opcache.revalidate_freqnow defaults to0whenhot_reloadis configured. With the default of2, the page fetched right after a change often came back unchanged. A value set inphp.ini, inPHP_INI_SCAN_DIRor with thephp_inidirective still takes precedence by @dunglas in #2680. - Caddy: Thread and request counts are now parsed as
int. On 32-bit platforms (linux/386,linux/arm/v6andlinux/arm/v7), out-of-range values wrapped to negative numbers, somax_threads 4294967295meantauto. They now return a range error by @dunglas in #2722. - Static builds:
types.his renamed tofrankenphp_types.h, because libwebp's header with the same name shadowed it and broke the build by @alexandre-daubois in #2728.
📖 Documentation
- Explain how to publish Mercure updates from
php-clithrough the hub's POST endpoint, and why detectingmercure_publish()while warming caches disables it in the web server too by @dunglas in #2718. - Fix the Russian translation by @chubakur in #2712.
💖 New Contributors
- @chubakur made their first contribution in #2712
- @zaccesss made their first contribution in #2726
- @nickchomey made their first contribution in #2717
- @sergehardy made their first contribution in #1926
Full Changelog: v1.13.1...v1.13.2