ai newsSo., 25. Okt.
EilmeldungOpenAIs php2shell-Checker prüft 65 Seiten, liefert aber nur UNKNOWN

OpenAIs php2shell-Checker prüft 65 Seiten, liefert aber nur UNKNOWN

Mit den Oktober-Sicherheitsupdates von PHP ist die Schwachstelle php2shell (CVE-2026-109618 und CVE-2026-109619) aufgetaucht, auf GitHub kursieren binnen Tagen mehrere exploit-PoC-Repos mit über 1.300 Sternen. Ein Test von OpenAIs neuem Checker gegen 65 betroffene Seiten ergab durchweg nur das Ergebnis UNKNOWN.

dev.toSonntag 01:37 · 25.10.DE4 Min. Lesezeit
Bild: dev.to

php2shell (CVE-2026-109618 / CVE-2026-109619) ist mit den Sicherheitsupdates von PHP vom 21. Oktober erschienen, und innerhalb weniger Tage füllte sich GitHub damit. Nach eigener Suche von GitHub sind mindestens drei Exploit-PoC-Repositories, die in dieser Woche erstellt wurden, bereits jeweils über 1.300 Sterne. OpenAIs Beitrag zu dieser Sammlung ist das Gegenteil eines PoC: openai/php2shell-checker, ein defensives Werkzeug, das verrät, ob eine Website ein verwundbares PHP betreibt, und zwar durch Auslesen der Versionskennung.

Es sind 99 Zeilen Node. Es sendet keine Exploit-Sonden. Und als ich es auf 65 echte Websites richtete, lieferte es 65 Mal dieselbe Antwort: UNKNOWN. Der Checker hat in allem, was er sehen kann, recht. Das Problem ist, dass Websites vor einem Jahrzehnt aufgehört haben, ihm das zu zeigen.

Die eigentliche Logik steckt in skills/phpcheck-url/scripts/phpcheck.js (die phpcheck.js auf der obersten Ebene ist ein Zwei-Zeilen-Stummel). Ausgedünnt sieht sie so aus:

const FIXED_IN = { ' 8.2 ': 35, ' 8.3 ': 36, ' 8.4 ': 27, ' 8.5 ': 12 } const OLDER_BRANCHES = new Set ([ ' 5.4 ', ' 5.5 ', ' 5.6 ', ' 7.0 ', ' 7.1 ', ' 7.2 ', ' 7.3 ', ' 7.4 ', ' 8.0 ', ' 8.1 ' ]) Enter fullscreen mode Exit fullscreen mode Das Werkzeug sendet eine HEAD-Anfrage (nur bei 405/501 mit GET als Rückfallebene), folgt niemals Weiterleitungen, liest nie den Body und durchsucht die Header Server und X-Powered-By per Regex nach PHP/x.y.z. Ist der Branch in FIXED_IN enthalten, entscheidet die Patch-Nummer. Handelt es sich um einen EOL-Branch, lautet die Antwort potenziell verwundbar, egal wie hoch die Patch-Nummer ist. Es wird nie ein korrigiertes 8.1 geben, also wird 8.1.beliebig markiert.

Wenn sowohl eine beruhigende als auch eine alarmierende Kennung auftaucht, berichtet das Werkzeug absichtlich die alarmierende ("Vorlieben für Warnungen und unbekannte Versionen statt für eine beruhigende Kennung"). Exit-Codes: 0 ok, 1 vulnerable, 3 unknown, 2 für fehlerhafte Argumente. Die eigene Testsuite lief bei mir mit 49 von 49 bestandenen Tests durch.

Was Versionszeichenketten-Logik angeht, ist das sorgfältige Arbeit. Also fütterte ich es direkt mit Versionszeichenketten, über einen lokalen Server, der eigens gebaute X-Powered-By-Header auslieferte:

advertised verdict why 8.2.34 potentially_vulnerable eine Stufe unter dem Fix 8.2.35 8.2.35 ok 8.3.36 ok exakte Grenze 8.4.26 potentially_vulnerable 8.4.27 ok 8.5.11 potentially_vulnerable 8.5.12 ok 8.1.34 potentially_vulnerable EOL-Branch-Regel 8.1.99 potentially_vulnerable die Patch-Nummer kann einen EOL-Branch nicht retten 7.4.33 potentially_vulnerable 5.6.40 potentially_vulnerable 8.2.34-5ubuntu2 potentially_vulnerable Distributions-Suffix geparst, Backport unsichtbar 8.2.35RC1 unknown Vorabversion, das Werkzeug ratet nicht 8.6.0 unknown Branch noch nicht in der Tabelle Enter fullscreen mode Exit fullscreen mode Jede Grenze liegt exakt dort, wo sie laut PHP-Advisory liegen sollte. Beachte die beiden ehrlichen Schwächen, die im Design angelegt und im README offengelegt sind: Ein Distributions-Build wie Ubuntus 8.2.34-5ubuntu2 wird markiert, selbst wenn Ubuntu den Fix zurückportiert hat (Header können das nicht unterscheiden), und ein ok "beschreibt nur die angegebene Version, es verifiziert die Installation nicht."

batch 1: 25 bekannte Seiten (wordpress.com, php.net selbst, Wikipedia, Drupal.org, Joomla.org, Magento, GitHub, Stack Overflow, BBC, NYT, Reddit, Etsy, Booking,...) batch 2: 40 weitere (phpBB, MediaWiki, Moodle, die Projektseiten von GNU/Apache/nginx/PostgreSQL, Sprach-Homepages,...) Ergebnis: 65 × UNKNOWN, "PHP-Version nicht gefunden" 64 von 65 senden in keinem Header eine PHP-Version 1 von 65 (mariadb.org) sendet X-Powered-By: Seravo, den Namen eines Hosting-Unternehmens, keine Version Enter fullscreen mode Exit fullscreen mode Null vulnerable. Null ok. Null Information, und genau das ist der Befund. expose_php = Off und header-bereinigende CDNs haben so vollständig gesiegt, dass selbst php.net kein PHP mehr ausweist.

Die Seiten, die am ehesten noch ein EOL-8.1 auf Shared Hosting betreiben, sind genau die, deren Kennungen, falls vorhanden, hinter dem liegen, was der Host konfiguriert hat. Und der anvisierte Nutzer des Checkers hat laut der eigenen Skills-Verpackung ("die PHP-Version prüfen, die meine Website ausliefert") ohnehin Serverzugriff. Es gibt im Repository einen zweiten Skill, phpcheck-server, der das lokale php -v liest. Der kann von einer fehlenden Kennung nicht getäuscht werden, weil er nie eine betrachtet.

Unfreundlich gelesen ist ein Versionskennungen-Checker im Jahr 2026 ein Metalldetektor an einem Strand, den alle bereits abgesucht haben. Fair gelesen ist er drei nützliche Dinge:

Mein Fazit: Führe die serverseitige Prüfung auf allem aus, was du selbst betreibst (php -v, vergleiche mit 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 und behandle alles ≤8.1 als erledigt). Nutze den URL-Checker für Seiten, die du nicht betreibst, mit der richtigen Erwartung: Eine Antwort bedeutet etwas, und Schweigen, was das moderne Web liefert, 65 von 65 Mal, bedeutet, dass die Ära der Kennungen vorbei ist, nicht dass das PHP darunter gepatcht ist.

Quellen: github.com/openai/php2shell-checker (Quellcode des Checkers, README, Testsuite), PHP-Advisory und korrigierte Veröffentlichungen vom 21. Oktober 2026 (php.net), GitHub-Repository-Suche nach php2shell-PoCs seit 2026-10-17. Die Header-Scans und die Matrix mit den gebauten Versionen stammen aus eigenen Läufen.

Automatisch übersetzt. Das Original auf Englisch ist unten aufklappbar.

Original (Englisch) anzeigen

php2shell (CVE-2026-109618 / CVE-2026-109619) landed with PHP's October 21 security releases, and GitHub filled up with it within days — by GitHub's own search, at least three exploit-PoC repos created this week are already over 1,300 stars each. OpenAI's contribution to the pile is the opposite of a PoC: openai/php2shell-checker, a defensive tool that tells you whether a site is running a vulnerable PHP — by reading its version banner.

It's 99 lines of Node. It sends no exploit probes. And when I pointed it at 65 real websites, it returned the same answer 65 times: UNKNOWN. The checker is correct about everything it can see. The problem is what websites stopped showing it a decade ago.

The real logic lives in skills/phpcheck-url/scripts/phpcheck.js (the top-level phpcheck.js is a 2-line shim). Stripped down:

const FIXED_IN = { ' 8.2 ': 35, ' 8.3 ': 36, ' 8.4 ': 27, ' 8.5 ': 12 } const OLDER_BRANCHES = new Set ([ ' 5.4 ', ' 5.5 ', ' 5.6 ', ' 7.0 ', ' 7.1 ', ' 7.2 ', ' 7.3 ', ' 7.4 ', ' 8.0 ', ' 8.1 ' ]) Enter fullscreen mode Exit fullscreen mode It sends a HEAD request (falling back to GET only on 405/501), never follows redirects, never reads the body, and regex-scans the Server and X-Powered-By headers for PHP/x.y.z. If the branch is in FIXED_IN, the patch number decides. If the branch is EOL, the answer is potentially_vulnerable no matter how large the patch number — there is no fixed 8.1, ever, so 8.1.anything is flagged.

If both a reassuring and an alarming banner show up, it deliberately reports the alarming one ("Prefer warnings and unrecognized versions over a reassuring banner"). Exit codes: 0 ok, 1 vulnerable, 3 unknown, 2 bad args. Its own test suite: 49/49 passing when I ran it.

As version-string logic goes, this is careful work. So I fed it version strings directly, through a local server emitting crafted X-Powered-By headers:

advertised verdict why 8.2.34 potentially_vulnerable one below the 8.2.35 fix 8.2.35 ok 8.3.36 ok exact boundary 8.4.26 potentially_vulnerable 8.4.27 ok 8.5.11 potentially_vulnerable 8.5.12 ok 8.1.34 potentially_vulnerable EOL branch rule 8.1.99 potentially_vulnerable patch number can't save an EOL branch 7.4.33 potentially_vulnerable 5.6.40 potentially_vulnerable 8.2.34-5ubuntu2 potentially_vulnerable distro suffix parsed, backport invisible 8.2.35RC1 unknown prerelease → refuses to guess 8.6.0 unknown branch not in the table yet Enter fullscreen mode Exit fullscreen mode Every boundary is exactly where the PHP advisory says it should be. Note the two honest failures baked into the design, both disclosed in its README: a distro build like Ubuntu's 8.2.34-5ubuntu2 gets flagged even if Ubuntu backported the fix (headers can't tell), and an ok "only describes the advertised version — it doesn't verify the installation."

batch 1: 25 well-known sites (wordpress.com, php.net itself, Wikipedia, Drupal.org, Joomla.org, Magento, GitHub, Stack Overflow, BBC, NYT, Reddit, Etsy, Booking,...) batch 2: 40 more (phpBB, MediaWiki, Moodle, the GNU/Apache/nginx/ PostgreSQL project sites, language homepages,...) result: 65 × UNKNOWN — "PHP version not found" 64 of 65 send no PHP version in any header 1 of 65 (mariadb.org) sends X-Powered-By: Seravo — a hosting company's name, not a version Enter fullscreen mode Exit fullscreen mode Zero vulnerable. Zero ok. Zero information — and that's the finding. expose_php = Off and header-stripping CDNs won so completely that even php.net doesn't advertise PHP.

The sites most likely to still run an EOL 8.1 on shared hosting are precisely the ones whose banners, if any, sit behind whatever their host configured — and the checker's target user, per its own skills packaging ("check the PHP version serving my site"), has server access anyway. There's a second skill in the repo, phpcheck-server, that reads the local php -v — that one can't be fooled by a missing banner, because it never looks at one.

Read uncharitably, a version-banner checker in 2026 is a metal detector on a beach everyone already swept. Read fairly, it's three useful things:

My take: run the server-side check on anything you operate ( php -v, compare against 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12, treat anything ≤8.1 as done). Use the URL checker on sites you don't operate with the right expectation: an answer means something, and silence — which is what the modern web returns, 65 times out of 65 — means the banner era is over, not that the PHP underneath is patched.

Sources: github.com/openai/php2shell-checker (checker source, README, test suite), PHP advisory and fixed releases of October 21, 2026 (php.net), GitHub repository search for php2shell PoCs created since 2026-10-17. Header scans and the crafted-version matrix are my own runs.

Originaltitel: OpenAI shipped a php2shell checker. I ran it against 65 sites. All 65 said UNKNOWN.Quelle: dev.to (dev.to). Original öffnen