GitLab is not affected by PHP2Shell (CVE-2026-109618 and CVE-2026-109619). The GitLab application is not written in PHP and does not run it to serve web requests, and our Security team has found no evidence of impact to GitLab-managed infrastructure. GitLab.com, GitLab Self-Managed, and GitLab Dedicated are not impacted.
PHP is a widely used programming language that runs on web servers and powers popular platforms like WordPress, Drupal, and Magento, so a flaw in PHP itself can affect many websites and applications. On October 21, 2026, the PHP project fixed two critical remote code execution flaws in PHP, together known as PHP2Shell (CVE-2026-109618 and CVE-2026-109619). PHP rates both 9.2 on CVSS v4.0. The flaws are in the PHP engine, not in any framework, library, or application code, so there is no application-level fix. Any web server that runs PHP is affected, including NGINX and Apache. The PHP project confirmed the vulnerability on Apache with mod_php, where an unauthenticated request can achieve remote code execution before any application code runs.
Upgrade every server and container that runs PHP to serve web requests to PHP 8.5.12, 8.4.27, 8.3.36, or 8.2.35, or to your distribution’s patched package now.
This guide is for security and platform teams with PHP projects on GitLab. It covers the fixed version for each PHP branch and distribution, how to use GitLab features to locate PHP projects across your groups, how to track remediation, and how to check for signs of compromise.
Upgrade PHP to a fixed version now
Upgrade the PHP runtime on every host and in every container image to a fixed version. Framework updates, Composer updates, input validation, and authentication don’t help, because PHP handles the request before application code runs.
| Branch | Fixed in |
|---|---|
| PHP 8.5.x | 8.5.12 |
| PHP 8.4.x | 8.4.27 |
| PHP 8.3.x | 8.3.36 |
| PHP 8.2.x | 8.2.35 (end of life December 31, 2026) |
| PHP 8.6 release candidates | 8.6.0RC4. The official php:8.6-rc image was still on RC3 on October 21, and RC3 does not have the fix. |
| PHP 8.1 and older | No official release. PHP published minimal source backports for 7.4, 8.0, and 8.1, and some distributions ship patched packages. |
If your PHP comes from a distribution package, upgrade that package. Fixed package versions as of October 22:
| Distribution | Fixed package |
|---|---|
| Ubuntu 26.04 | php8.5 8.5.4-0ubuntu1.5 |
| Ubuntu 24.04 | php8.3 8.3.6-0ubuntu0.24.04.13 |
| Ubuntu 22.04 | php8.1 8.1.2-1ubuntu2.28 |
| Debian 13 | php8.4 8.4.27-1~deb13u1 |
| Debian 12 | php8.2 8.2.35-1~deb12u1 |
| Alpine 3.24 | php83 8.3.36, php84 8.4.27, php85 8.5.12 |
| RHEL 10 | php 8.3.36-1.el10_2 (RHSA-2026:87070), php8.4 8.4.27-1.el10_2 (RHSA-2026:87071) |
| RHEL 9 | php 8.0.30-8.el9_8.1 (RHSA-2026:87151), php:8.2 8.2.35-1 (RHSA-2026:87072), php:8.3 8.3.36-1 (RHSA-2026:87079); php:8.4 had no fix yet on October 22 |
| RHEL 8 | php:7.4 7.4.33-8 (RHSA-2026:87080); check Red Hat’s CVE pages for php:8.2. Retired streams (7.2, 7.3, 8.0) get no fix |
Sources: Ubuntu, Debian, Alpine, and Red Hat security trackers, as of October 22, 2026.
Ubuntu, and Red Hat for its 7.4 and 8.0 packages, keep the old upstream version number and backport the fix. Compare the package versions rather than php -v. Restart every process that runs PHP after upgrading.
Rebuild your container images. If your image uses a floating tag of the official php image, such as php:8, php:8.3, php:8.3-apache or php:latest, rebuild it with docker build --pull and redeploy it. Images that pin a patch version, such as php:8.3.35-apache, need the tag changed to the fixed version first. Images built on derivatives such as wordpress or drupal get the fix only after their maintainers publish an updated image, so check the upstream image before you rebuild.
Locate PHP projects across your GitLab groups
Any project that runs PHP to serve web requests needs a fixed version, including the ones that are easy to forget, such as an internal dashboard, a marketing site, or a CI job image. Finding them takes two views: a static search of what your repositories declare and your images contain, and a runtime inventory of what actually runs. GitLab covers the static view with two features. Use both, in this order.
1. Container scanning
Container scanning reports vulnerabilities in operating system packages, so it finds PHP installed with apt, apk, or dnf, and it reports the two CVEs once they reach the scanner’s vulnerability database. To turn it on for a project, add the template to .gitlab-ci.yml:
include:
- template: Security/Container-Scanning.gitlab-ci.yml
You can also use a group-level scan execution policy to turn container scanning on for every project in a group at once. When a policy is enabled, the next time a pipeline is run, it will be run with container scanning. Container scanning results for the default branch can be reviewed in the Vulnerability Report after the scanner completes.
Additionally, you can set up Merge Request Approval policies with container scanning. With merge request approvals in play, if a code change contains PHP2Shell, the policy will block a merge without approval from the selected parties.
Container scanning detects only PHP installed as a package. PHP compiled from source, including the official php images, has no package record, so a project can pass container scanning and still run a vulnerable PHP. Code search covers that gap.
2. Code search
Exact code search can find the two types of files that indicate a PHP project. Run these at the top-level group with regular expression mode enabled (the .* toggle at the right of the search box):
- Container base images: This query searches for every file GitLab detects as a Dockerfile. The pattern matches any image whose name or tag contains php, so it also finds derivatives such as wordpress, frankenphp, or bitnami/php-fpm. Expect a few false positives that you can rule out by reading the result:
lang:Dockerfile ^FROM.*php - Composer projects: This query finds projects that use PHP even when they have no Dockerfile, or when the Dockerfile takes its image from a build argument such as
FROM $BASE_IMAGE:
file:composer\.json$
Exact code search covers the default branch only. On GitLab.com it is on by default for paid plans. On GitLab Self-Managed instances an administrator must install Zoekt first. GitLab Dedicated doesn’t support exact code search.
For each result, confirm the version. You can check the FROM php:<tag> line, or run php -v in the running container, and compare it with the table above. The group dependency list shows Composer packages and framework versions but not the PHP runtime version.
3. Compare with your runtime inventory
Container scanning and code search show what your projects declare and build, not what runs. PHP can run outside your GitLab projects, for example on web servers with mod_php or PHP-FPM enabled only in their configuration, on hosts configured by hand, or in containers that still run in clusters without an active pipeline. Compare the static results with an inventory of your running workloads from your configuration management (Ansible, Puppet, Chef, etc.), cloud, or VM inventory tools. For Kubernetes, operational container scanning scans the images that run in your clusters, with the same package-only detection as container scanning. Treat every PHP runtime that appears in only one of the two views as a gap to investigate.
Remediate at scale with GitLab Duo Agent Platform
Start with asking GitLab Duo Agentic Chat to:
- collect every container scanning finding for CVE-2026-109618 and CVE-2026-109619 across the group from the vulnerability report (requires an Ultimate subscription)
- run the code search queries above across the group, review each hit and read the PHP version from the Dockerfile or the Composer files
- open a merge request per affected project that bumps the base image tag or the package to the fixed version, and assign it to the right maintainer
- track the whole effort in an epic with one issue per project, and is closed when the fixed version is deployed and confirmed
From each issue, the Developer Flow can open a merge request that updates the base image tag or package to a fixed version. Turn on automatic reviews with the Code Review Flow to get a first review that follows your custom review instructions. Review and merge each merge request, then close the issue once the fixed version is deployed.
Searches find candidates, but a security or platform engineer still has to review each match, resolve CI includes, and tell what the code declares apart from what actually runs. An example agent skill from the GitLab Developer Advocacy team handles this work. It runs on GitLab Duo Agent Platform and with agents that use GitLab MCP server or the glab CLI, such as Claude Code, Codex, and Cursor.
The skill checks container images, CI jobs, OS packages, configuration management variables, Composer pins, and environments. It returns a cited findings table with deployment evidence, and open gaps. The skill is read-only: It makes no changes, and remediation merge requests remain a separate, reviewed step. It cannot confirm what is running on hosts it cannot access, so verify those directly. Adapt the skill to your own environment before you use it.

Check for compromise
Reports of exploitation differ. Security researchers reported an exploit attempt on October 17, 2026, before public disclosure, and further reports of exploitation followed the release. The PHP project identified no functional exploits at the time of release. If an internet-facing server ran a vulnerable PHP version, review its logs from October 17, 2026, onward for:
- Multipart requests followed by memory-limit errors or repeated HTTP 500 responses
- Unusually large or malformed
PHPSESSIDresponse cookies - Unexplained PHP worker restarts, or shell processes started by PHP workers
- Unexpected files on the PHP web server, outbound connections from PHP workers, or unexpected cron entries
A successful exploit can return HTTP 200 and leave the worker running, so an absence of errors doesn’t rule out compromise. If you find signs of exploitation, isolate the server and start an incident investigation. Where possible, capture memory, disk, and logs before patching and restarting. Restarting PHP workers may erase evidence. CVE-2026-109619 can also expose process memory, even when an attacker doesn’t achieve code execution. Rotate any credentials, tokens, or keys the PHP process could read.
Note: Scanners may flag the Gemnasium dependency scanning image (gemnasium:6), deprecated since GitLab 17.9, for its bundled PHP. It is used only as a command-line tool and never handles HTTP requests, so it is not exploitable, and a fixed version has already shipped under the same tag.
Timeline
| Date | What happened |
|---|---|
| August 1 | Calif discovers the first flaw during an AI-assisted PHP audit and reports it to PHP on August 11; Wiz Research independently finds and reports the flaws on August 24. |
| October 17 | Amazon’s honeypots record the first known exploit attempt, while the flaws are still under embargo. |
| October 20 | PHP announces that a security release fixing two critical vulnerabilities will ship on October 21. |
| October 20 | Vulnerability details leak before coordinated disclosure. (Huntress) |
| October 21, 14:00 UTC | PHP releases 8.5.12, 8.4.27, 8.3.36 and 8.2.35 and publishes the advisories. |
































