---
title: "PHP2Shell: from vulnerable PHP versions to a reviewable pull request with Harbyn | Harbyn"
description: "Follow a public Harbyn scan from PHP2Shell findings to a real update PR, including exact version pins, floating tags and the decisions left for review."
canonical: "https://harbyn.com/blog/php2shell-production-runtime"
last-updated: 2026-10-22
---

# PHP2Shell: from vulnerable PHP versions to a reviewable pull request with Harbyn

Published October 22, 2026 by Harbyn. Tags: php, security, php2shell, developer-tools.

When a critical PHP update lands, the announcement is only the beginning. The next question is specific to your project: where is the affected version declared, and what needs to change?

PHP2Shell gave us a concrete example. We ran Harbyn against a public demo repository containing several ways of declaring PHP versions. The scan reported six findings across eleven files, and Harbyn opened a pull request updating two exact version pins.

You can inspect the [scan execution](https://github.com/harbyn/php2shell-demo/actions/runs/39718957930) and the [actual pull request](https://github.com/harbyn/php2shell-demo/pull/1). Here is what happened and how to try the same workflow on your own repository.

## What happened with PHP2Shell

On October 21, 2026, PHP released fixes for two critical vulnerabilities, CVE-2026-109618 and CVE-2026-109619, that can allow unauthenticated remote code execution. The fixed upstream releases were **8.2.35, 8.3.36, 8.4.27 and 8.5.12**. See the [official PHP security announcement](https://www.php.net/archive/2026.php#2026-10-21-5).

For a development team, acting on that announcement means finding the PHP declarations spread through the repository. The runtime might be pinned in a Dockerfile, referenced in Compose, configured in a workflow, or represented in Composer settings. Those declarations do not all mean the same thing, so they should not all receive the same edit.

## The demonstration: six findings, one reviewable PR

Our [demo repository](https://github.com/harbyn/php2shell-demo) is a small fictional PHP application created for this demonstration. It includes exact version pins, floating versions, a Composer requirement and a PHP 8.1 image.

Using Harbyn, the GitHub Action scanned eleven files and reported six lines requiring attention. Harbyn then opened a PR for the supported updates.

This gives us a traceable path from the security announcement to the declarations in the repository and the proposed changes. The evidence is available in the execution log and the diff, rather than an illustrative terminal screenshot.

## Why the findings led to different actions

The six findings were not six identical fixes:

| Declaration in the demo | What to do |
| --- | --- |
| Two exact PHP version pins | Update to the corrected patch release in the same PHP branch. |
| Two floating versions | Rebuild or update the relevant environment and check the runtime actually in use. |
| A Composer PHP requirement | Review compatibility requirements separately from the installed interpreter. |
| A PHP 8.1 image | Assess a move to a supported branch, including application compatibility. |

A floating tag such as `php:8.3-fpm` can stay unchanged while an older image remains deployed. There may be no version string to replace in the Dockerfile; the work is in obtaining and deploying a corrected image.

Older PHP branches also need a different decision. Moving an application from PHP 8.1 to a supported branch can affect compatibility. Distribution or extended-support packages may have backported fixes, so check the security advisory for the packages you actually use. The [PHP announcement](https://www.php.net/archive/2026.php#2026-10-21-5) discusses those options.

## Inside the pull request

The [generated PR](https://github.com/harbyn/php2shell-demo/pull/1) contains two targeted changes.

In `Dockerfile`, it updates the PHP base image:

```diff
-FROM php:8.3.35-fpm
+FROM php:8.3.36-fpm
```

In `composer.json`, it updates `config.platform.php`:

```diff
-      "php": "8.3.35"
+      "php": "8.3.36"
```

The second change deserves an explanation. Composer's platform setting tells dependency resolution which PHP version to assume. It does not install or upgrade PHP. Updating it alongside the Dockerfile aligns that assumption with the intended runtime. See [Composer's platform dependency documentation](https://getcomposer.org/doc/articles/composer-platform-dependencies.md).

The PR brings the proposed edits together for review. After reviewing them, the team still builds and deploys the updated image, replaces old instances and verifies the runtime serving requests. That is how the repository change reaches the application.

## Try Harbyn on your repository

From your repository directory, run:

```sh
npx harbyn scan
```

The scanner runs locally, downloads Harbyn's signed change feed and checks supported declarations without uploading your source code.

Review the reported files, lines and sources. To set up the PR workflow, follow the [Harbyn documentation](https://harbyn.com/docs).

PHP2Shell is one example of the problem Harbyn helps developers handle: an external change becomes relevant to a specific line in a repository. Harbyn connects that change to the code and, where a supported fix is available, prepares the update for review.

[Run a scan on your project](https://harbyn.com), or explore the [public PHP2Shell PR](https://github.com/harbyn/php2shell-demo/pull/1) first.
