AIREITER

Руководство по OpenAI Codex PHP2Shell Checker: как правильно читать UNKNOWN

Последнее обновление: 2026-10-22 09:15:55

php2shell-checker от OpenAI полезен для первичной проверки, но сам по себе не доказывает безопасность сервера. Инструмент сравнивает версию PHP, полученную из HTTP-заголовков или через php -v, с заданными порогами исправлений. Поэтому скрытый заголовок может дать результат UNKNOWN, а backport-патч от дистрибутива — заставить исправный сервер выглядеть уязвимым.

Репозиторий OpenAI php2shell-checker на GitHub

Сначала разберитесь со статусами

Официальный репозиторий OpenAI использует три основных статуса. Это сигналы для первичной сортировки, а не полноценная оценка уязвимости.

РезультатКод выходаЧто означаетЧто делать дальше
OK0Распознанная ветка достигла минимальной исправленной версии или находится выше неёПроверить, что PHP-процесс, обслуживающий веб-трафик, использует именно эту версию
VULNERABLE1Обнаруженная версия ниже минимальной исправленной версииОбновить runtime, обслуживающий сайт, перезапустить его воркеры и повторить обе проверки
UNKNOWN3Инструмент не смог определить распознанную версию или получить подходящий ответПроверить сервер локально и не считать его исправленным
Некорректные аргументы2Сама команда указана неверноИсправить команду и запустить её снова
Коды результатов PHP2Shell Checker

Что именно выпустила OpenAI

В публичном репозитории php2shell-checker находятся Node.js-скрипт, тесты и два навыка Codex: phpcheck-url для доступного по сети сайта и phpcheck-server для сервера, к которому у вас есть доступ. Инструмент собирает сведения о версии, но не эксплуатирует цель и не сканирует код приложения.

Выбирайте режим проверки под задачу

Проверка публичного URL

Клонируйте или скачайте репозиторий, затем запустите Node.js-скрипт для нужного сайта:

node phpcheck.js "https://example.com"

При удалённой проверке отправляется HTTP-запрос HEAD. На GET инструмент переходит только если сервер отвечает кодом 405 или 501. Проверяются заголовки X-Powered-By и Server; перенаправления не обрабатываются, содержимое ответа не анализируется.

CDN, reverse proxy, настройка expose_php=off или нестандартная конфигурация сервера могут удалить версию PHP ещё до того, как ответ попадёт в checker. Результат VULNERABLE означает, что систему нужно обновить; отсутствие заголовка требует локальной проверки.

Проверка локального PHP-бинарника

На машине с установленным PHP используйте:

node phpcheck.js --local

Команда запускает php -v для бинарника, который находится в текущем PATH. Это не доказывает, что тот же бинарник обслуживает сайт: на одном хосте могут отдельно использоваться CLI, PHP-FPM, CGI, модуль Apache, контейнер или сборка из исходников.

После локальной проверки определите runtime, подключённый к веб-серверу. В контейнерной инфраструктуре смотрите на запущенный контейнер, а не только на тег его образа. Если PHP установлен из пакета, проверьте нужный пул PHP-FPM или модуль Apache, а также changelog пакета от поставщика.

Установка и использование навыков Codex

В официальном README оба навыка устанавливаются одной командой Codex:

$skill-installer install both skills from https://github.com/openai/php2shell-checker

После этого выберите интерфейс, соответствующий вашему уровню доступа:

$phpcheck-url check https://example.com
$phpcheck-server check the PHP version serving my site

Codex использовать необязательно. Для CI-задач и минимальных хостов достаточно прямого запуска Node.js-команды. В автоматизации добавьте --json: поле patch_status вернёт ok, vulnerable или unknown, и скрипту не придётся разбирать текстовый вывод терминала.

Проверка скачанного checker

В репозитории используется встроенный тестовый runner Node:

node --test phpcheck.test.js

Набор тестов проверяет CLI через локальные HTTP-серверы и использует поддельный PHP-исполняемый файл для локальных сценариев. Согласно README, для запуска не нужны ни настоящая установка PHP, ни доступ к внешнему сайту.

Считайте UNKNOWN результатом для отладки

UNKNOWN означает, что данных недостаточно. Сайт может скрывать версию PHP, использовать нераспознанную ветку, не отвечать или работать на более новой предварительной версии. Ни один из этих вариантов не подтверждает наличие исправления.

Пользователь @jvr0x кратко описал ограничение так:

«Это всего лишь сравнение версии с порогами от 20 октября, поэтому скрытые заголовки дают UNKNOWN».

Удалённая команда видит HTTP-ответ, но не процесс за reverse proxy. Если заголовок скрыт, нужно проверять сервер, а не бесконечно повторять запросы к URL.

После UNKNOWN действуйте по следующей схеме:

  1. Запустите node phpcheck.js --local на хосте, который обслуживает сайт.
  2. Определите, куда попадает запрос: в PHP-FPM, CGI, Apache mod_php или контейнер.
  3. Проверьте changelog пакета от поставщика на наличие backport-патчей.
  4. После обновления перезапустите нужные воркеры PHP-FPM или Apache.
  5. Проверяйте именно путь, обслуживающий сайт, а не только бинарник php по умолчанию в shell.

Без SSH проверка URL может быть единственным вариантом для первого прохода. Если shared-хостинг скрывает версию в заголовке, провайдер должен подтвердить runtime, обслуживающий сайт, ревизию пакета и факт перезапуска.

Одной таблицы версий для решения недостаточно

Checker считает минимальными исправленными upstream-релизами для соответствующих веток PHP 8.5.12, 8.4.27, 8.3.36 и 8.2.35. Официальные тесты подтверждают: 8.4.26 получает статус VULNERABLE, а 8.4.27 — OK. Сам PHP называет 8.5.12, 8.4.27, 8.3.36 и 8.2.35 релизами безопасности.

ВеткаМинимальный исправленный upstream-релизПредыдущий релиз, признанный уязвимым
PHP 8.58.5.128.5.11
PHP 8.48.4.278.4.26
PHP 8.38.3.368.3.35
PHP 8.28.2.358.2.34
Ситуация при развёртыванииПочему простое сравнение версий может ввести в заблуждениеКакие данные использовать
Скрытый заголовок X-Powered-By или ServerУдалённый checker не может определить PHPЛокальная инвентаризация runtime
Пакет безопасности Debian или UbuntuПоставщик мог добавить исправление в старую upstream-версию, не меняя её номерРекомендации поставщика и changelog пакета
PHP-FPM и CLI на одном хостеphp -v может описывать CLI, а не HTTP-воркерКонфигурация веб-сервера и FPM
Закэшированный контейнер или закреплённый digestТег в registry может быть актуальным, пока запущенный контейнер остаётся старымID образа и версия запущенного контейнера
Воркеры Apache или FPM не перезапущеныИсправленные файлы уже находятся на диске, но старые воркеры всё ещё работаютВремя запуска процесса и проверка после перезапуска
Неподдерживаемая ветка или prereleaseChecker может не распознать состояние патча от поставщикаУведомление безопасности PHP или поставщика

В разделе ограничений репозитория сказано, что инструмент предполагает наличие исправления в более поздних стабильных патч-релизах перечисленной ветки и не может самостоятельно проверить сам факт исправления. Дистрибутив способен выпустить security backport, не меняя upstream-номер версии, поэтому его changelog надёжнее, чем одно только отображаемое число.

Обновление WordPress, Drupal, Laravel или другого PHP-приложения не исправляет сам движок PHP. Обновите пакет или образ runtime, перезапустите воркеры и проверьте процесс, принимающий веб-запросы.

FAQ

Какой результат позволяет закрыть задачу по устранению проблемы в production?

Ни один результат не должен закрывать задачу сам по себе. Статус OK нужно сопоставить с используемым SAPI, статусом backport-патча от поставщика, всеми нужными vhost и контейнерами, а также подтверждением, что после обновления воркеры были перезапущены.