Repository navigation
fix(docker): refuse to build an image with PHP below 8.4.27 (CVE-2026-109618) - #14
Merged
Merged
Conversation
CVE-2026-109618 / CVE-2026-109619 are RCE flaws in PHP's longjmp-based OOM and fatal-error handling (CVSS 9.2, exploited in the wild). They are fixed in PHP 8.4.27 and affect every SAPI, FrankenPHP included. PHP is compiled into the FrankenPHP base image rather than installed from apt — the base image even pins `php*` to Pin-Priority -1 — so the existing `apt-get upgrade` layer cannot patch it. Only a rebuilt base image can. Add a MIN_PHP_VERSION floor that fails the build instead of silently shipping a vulnerable runtime; it clears itself once the build pulls a patched base. The release workflow also built without `pull: true`, unlike the CI job, so the pipeline that actually ships to production could resolve a stale cached base layer — exactly the path that would produce such an image. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fourth repo on the same
dunglas/frankenphp:1-php8.4base — same fix as NoiXdev/marketix#117, NoiXdev/kontorfix#1 and NoiXdev/inventorix#53.CVE-2026-109618 / CVE-2026-109619 are RCE flaws in PHP's
longjmp()-based OOM and fatal-error handling (CVSS 4.0 9.2, exploited in the wild since 21 Oct 2026), fixed in PHP 8.4.27. FrankenPHP is explicitly among the affected SAPIs.Dockerfile—ARG MIN_PHP_VERSION=8.4.27plus a guard layer right after theFROM. The build fails rather than silently shipping a vulnerable runtime, and clears itself once a patched base is pulled..github/workflows/release.yml— addpull: true. Thedockerjob inci.ymlalready had it (with a comment explaining exactly why); the release job did not — so the pipeline that actually ships could resolve a stale cached base layer.Why apt cannot do this instead
The
apt-get upgradealready in this Dockerfile cannot reach PHP, verified inside the image:dpkg -l | grep -c php→ 0. PHP is built from source into/usr/local; no apt package owns/usr/local/bin/php./etc/apt/preferences.dwithPackage: php*/Pin-Priority: -1, so Debian's ownphp8.4-cli(which does have 8.4.27 intrixie-security) resolves toCandidate: (none).ldd $(which frankenphp)→libphp.so => /usr/local/lib/libphp.so, built--enable-embed --enable-zts. An apt-installed PHP would sit unused in/usr/binand leavelibphp.sountouched — while possibly turning a scanner green. The guard therefore checks the running interpreter'sPHP_VERSION, not a package list.Verification
Guard exercised in both directions against the real base image:
FATAL: base image ships PHP 8.4.27, need >= 8.4.28 (CVE-2026-109618/109619)The
dockerjob in CI builds the image on this PR, so the guard is exercised by CI here too.Note on the published image
The guard only governs future builds — it cannot change an image that already exists. The currently published image was built before PHP 8.4.27 existed and therefore still contains 8.4.26; a
docker pullon a server will not change that, because the base image is baked into the layers at build time. A release run is required after this merge for the shipped image to carry the fix.Out of scope
Kept to the minimum needed for a secure image:
apt-get upgradecan be served from the BuildKit cache indefinitely. Unrelated to this CVE, same class of staleness.ci.ymlhas noschedule:trigger, so the Trivy gate only runs when someone pushes.🤖 Generated with Claude Code