Aktuelle Lage: PHP2Shell. Zwei kritische PHP-Lücken (CVSS 9.2) erlauben Schadcode ohne Anmeldung. Patches seit 21.10.2026.Was jetzt zu tun ist →

Statische Analyse: PHPStan und Psalm

PHPStan und Psalm finden Fehler im PHP-Code, ohne ihn auszuführen. Psalm verfolgt zusätzlich unsichere Datenflüsse. Lücken im PHP-Interpreter selbst finden beide nicht.

Stand 5 Min. LesezeitPHP-Wissen

Kurz gesagt: Statische Analyse prüft PHP-Code, ohne ihn auszuführen, und findet so Typfehler, undefinierte Variablen, toten Code und Aufrufe auf möglicherweise leeren Werten. Die beiden verbreiteten Werkzeuge sind PHPStan (Regelstufen 0 bis 10) und Psalm (Fehlerstufen 1 bis 8, dazu eine Taint-Analyse für unsichere Datenflüsse). Sie finden Fehler in Ihrer Anwendung, nicht im PHP-Interpreter; gegen Lücken wie PHP2Shell hilft nur das PHP-Update.

Was ist statische Analyse?

Ein Test führt Code aus und vergleicht das Ergebnis. Statische Analyse liest den Code dagegen wie ein sehr gründlicher Prüfer und folgert aus Typen, Rückgabewerten und Aufrufen, wo etwas schiefgehen kann. Sie findet Fehler auch in Zweigen, die kein Test je erreicht.

Für Entscheider ist der Nutzen einfach: Fehler, die vor dem Livegang gefunden werden, kosten einen Bruchteil von Fehlern, die Kunden bemerken. Für Entwickler ist sie ein ständiger Begleiter, der in der Entwicklungsumgebung und in der CI-Pipeline mitläuft. Schlägt die Analyse bei einer Änderung an, wird diese nicht übernommen, bis der Fehler behoben ist. So wächst kein neuer Altbestand nach, während der vorhandene schrittweise abgebaut wird. Gemeinsam mit Tests mit PHPUnit und Pest bildet sie das Fundament der Codequalität.

PHPStan: Regelstufen von 0 bis 10

PHPStan wird als Entwicklungsabhängigkeit installiert und benötigt zum Laufen PHP ab 7.4:

composer require --dev phpstan/phpstan
vendor/bin/phpstan analyse src tests

Ohne weitere Angabe prüft PHPStan nur das Nötigste. Die Strenge steuern Sie über elf Stufen, jede schließt die darunterliegenden ein:

Stufe Was zusätzlich geprüft wird (Auswahl)
0 unbekannte Klassen und Funktionen, falsche Zahl von Argumenten, immer undefinierte Variablen
3 Rückgabetypen und Typen, die Eigenschaften zugewiesen werden
5 Typen der Argumente bei Funktions- und Methodenaufrufen
6 fehlende Typangaben
8 Methodenaufrufe und Eigenschaftszugriffe auf Werte, die null sein können
10 strengster Umgang mit mixed, auch bei fehlenden Typen

Mit --level max läuft immer die höchste Stufe. Die Dokumentation warnt allerdings, dass ein Upgrade von PHPStan dann viele neue Meldungen bringen kann. Ein typischer Fund ab Stufe 8:

<?php
function kundenname(?Kunde $kunde): string
{
    return $kunde->name();   // PHPStan: Aufruf auf einem Wert, der null sein kann
}

PHPStan einführen ohne Fehlerflut: die Baseline

In gewachsenen Projekten meldet PHPStan auf hoher Stufe oft Hunderte Stellen. Die Baseline löst das Problem: Sie speichert alle bestehenden Meldungen in einer Datei, und PHPStan meldet ab dann nur noch neue Fehler.

vendor/bin/phpstan analyse --level 6 src tests --generate-baseline

Die erzeugte Datei phpstan-baseline.neon binden Sie in die Konfiguration ein:

includes:
    - phpstan-baseline.neon

parameters:
    level: 6
    paths:
        - src
        - tests

So bleibt der Altbestand sichtbar dokumentiert, während neuer Code von Anfang an sauber sein muss.

Psalm und die Taint-Analyse

Psalm verfolgt ähnliche Ziele wie PHPStan. Die Stufen laufen umgekehrt: 1 ist die strengste, 8 die nachsichtigste, Standard ist 2. Psalm benötigt PHP ab 8.2 und wird so eingerichtet:

composer require --dev vimeo/psalm
./vendor/bin/psalm --init
./vendor/bin/psalm --taint-analysis

Die Taint-Analyse ist für Sicherheit besonders interessant. „Taint“ heißt Verunreinigung: Psalm markiert Daten aus Quellen, die ein Angreifer kontrollieren kann, etwa $_GET, $_POST, $_COOKIE, $_REQUEST oder php://input. Dann verfolgt es, ob diese Daten ungeschützt an gefährlichen Stellen ankommen, den sogenannten Senken: Ausgabe mit echo, include, header oder SQL-Abfragen. Zu den eingebauten Kategorien gehören unter anderem sql, html, shell, include, eval, ssrf und unserialize.

<?php
// Psalm meldet einen Fluss von $_GET in die HTML-Ausgabe (Kategorie html)
echo 'Hallo ' . $_GET['name'];

// Behoben: Ausgabe kontextgerecht maskieren
echo 'Hallo ' . htmlspecialchars($_GET['name'] ?? '', ENT_QUOTES, 'UTF-8');

Die Psalm-Dokumentation nennt die Grenzen offen: Die Analyse nimmt an, dass Maskierung korrekt erfolgt. Feine Fehler, etwa fehlende Anführungszeichen um ein HTML-Attribut, können trotzdem Lücken lassen. Psalm empfiehlt deshalb parametrisierte Abfragen für SQL und kontextbewusste Templates für HTML. Ergebnisse lassen sich im SARIF-Format ausgeben, das unter anderem GitHub Code Scanning versteht.

Statische Analyse und Sicherheit nach PHP2Shell

Hier lohnt eine ehrliche Abgrenzung. PHP2Shell, also CVE-2026-109618 und CVE-2026-109619, steckt im PHP-Interpreter. Kein Werkzeug, das Ihren Anwendungscode liest, findet diese Lücken, und keine Codeänderung schließt sie. Das leistet nur das Update auf PHP 8.5.12, 8.4.27, 8.3.36 oder 8.2.35.

Trotzdem trägt statische Analyse zur Sicherheit bei, an drei Stellen:

  1. Upgrade-Fähigkeit: Sie findet Code, der auf neuen PHP-Versionen nicht mehr läuft. Damit sinkt die Hürde, von 8.1 oder 8.2 auf eine unterstützte Version zu wechseln.
  2. Eigene Lücken: Die Taint-Analyse findet Wege für SQL-Injection, Cross-Site-Scripting oder Dateieinbindung. Das PHP-Projekt stellt in seiner Sicherheitsrichtlinie klar, dass ungeprüfte Eingaben an Funktionen wie mysqli_query() kein Fehler von PHP sind, sondern in der Verantwortung der Anwendung liegen.
  3. Robustheit: Viele fatale Fehler entstehen durch Aufrufe auf null oder falsche Typen. php.net rät im Zusammenhang mit CVE-2026-109619 ausdrücklich, von außen auslösbare fatale Fehler in der Anwendung zu beheben.

Statische Analyse ersetzt kein Sicherheits-Code-Review durch Menschen, sie macht es aber effizienter, weil Routinefehler vorher aussortiert sind.

Wie hilft PHP SOS konkret?

Im Rahmen von Sicherheitsaudit und Penetrationstest gehen wir so vor:

  • Werkzeuge einrichten: PHPStan oder Psalm mit passender Stufe und Baseline, eingebunden in Ihre bestehende Pipeline.
  • Sicherheitsfunde bewerten: Wir prüfen die Ergebnisse der Taint-Analyse und trennen echte Risiken von Fehlalarmen.
  • Upgrade vorbereiten: Wir zeigen, welche Stellen einen Wechsel auf eine unterstützte PHP-Version blockieren.
  • Ergebnisse übergeben: Sie erhalten eine priorisierte Liste mit konkreten Codestellen für Ihr Team oder Ihre Agentur.

Häufige Fragen

Was ist der Unterschied zwischen PHPStan und Psalm?

Beide prüfen Typen und finden Fehler ohne Ausführung. PHPStan zählt seine Stufen von 0 (locker) bis 10 (streng), Psalm von 8 (locker) bis 1 (streng). Psalm bringt eine eingebaute Taint-Analyse für Sicherheitsprobleme mit.

Kann ich PHPStan in ein altes Projekt einführen?

Ja. Mit einer Baseline speichert PHPStan alle bestehenden Meldungen in einer Datei und meldet danach nur neue Fehler. So startet das Team ohne Fehlerflut und baut Altlasten schrittweise ab.

Findet statische Analyse PHP2Shell?

Nein. PHP2Shell steckt im PHP-Interpreter, nicht in Ihrem Code. Dagegen hilft nur das PHP-Update. Statische Analyse hilft aber, den Code für neue PHP-Versionen vorzubereiten, damit das Update schneller möglich ist.

Welche Stufe sollte man wählen?

Für den Einstieg eine niedrige Stufe ohne Baseline oder eine höhere Stufe mit Baseline. Wichtiger als die Zahl ist, dass die Analyse bei jeder Änderung automatisch läuft und neue Fehler nicht durchlässt.

Quellen

Sofort-Kontakt

Jede Stunde zählt. Schreiben Sie uns jetzt.

Schildern Sie kurz System, PHP-Version und Beobachtung. Wir melden uns, klären die Lage und arbeiten remote, bis der Vorfall abgeschlossen und dokumentiert ist.

Sofort-Hilfe