Gute Nachrichten zuerst: Euer Legacy-System wurde wahrscheinlich noch nicht gehackt. Schlechte Nachrichten: "wahrscheinlich" ist keine beruhigende Aussage, wenn es um Produktionsdaten geht. Legacy-Code und Sicherheitsprobleme gehen häufig Hand in Hand – nicht weil die ursprünglichen Entwickler sorglos waren, sondern weil sich Sicherheitsstandards weiterentwickelt haben. Was 2008 als ausreichend galt, ist heute eine bekannte Angriffsfläche mit fertigen Exploit-Kits.

Die häufigsten Schwachstellen, die ich finde

SQL-Injection

Datenbankabfragen, die Nutzereingaben per String-Konkatenation zusammenbauen, sind das klassischste Problem. "SELECT * FROM users WHERE id = " . $_GET['id'] ist kein hypothetisches Beispiel – ich sehe solche Konstrukte regelmäßig, manchmal sogar in Systemen, die gerade erst gebaut wurden. Die Lösung sind Prepared Statements mit PDO oder einem Query Builder. Keine Ausnahmen.

Cross-Site Scripting (XSS)

Nutzereingaben, die direkt in HTML ausgegeben werden, ohne htmlspecialchars(), erlauben es Angreifern, JavaScript im Browser anderer Nutzer auszuführen. Besonders gefährlich in Anwendungen mit gespeicherten Inhalten – Kommentaren, Profilen, Nachrichten. Also genau den Stellen, die Nutzer am meisten vertrauen.

Veraltete Session-Mechanismen

Session-IDs in der URL, fehlende HttpOnly- und Secure-Flags auf Cookies, keine Session-Regenerierung nach dem Login – das sind die typischen Muster, die ich in alten PHP-Anwendungen antreffe. Jedes einzelne davon ist heute ein bekannter Angriffsvektor. Zusammen ergeben sie ein interessantes Paket.

Unsichere Datei-Uploads

Datei-Uploads ohne Typprüfung, ohne Größenbeschränkung, mit ausführbaren Pfaden – ein häufig unterschätztes Risiko, das Remote Code Execution ermöglicht. Sprich: jemand lädt eine PHP-Datei hoch und führt sie aus. Das Ende der Geschichte schreibt sich leider oft selbst.

Viele dieser Schwachstellen sind kein Geheimnis – sie tauchen regelmäßig in den OWASP Top 10 auf, der von der Open Worldwide Application Security Project gepflegten Referenzliste der kritischsten Sicherheitsrisiken für Webanwendungen. SQL-Injection und XSS gehören seit Jahren dazu – und trotzdem begegnen sie mir immer noch im Produktivbetrieb.

Mein Vorgehen bei der Sicherheitsanalyse

Ich beginne mit automatisierten Tools: psalm mit dem Taint-Analyse-Plugin findet viele Injektionspfade statisch. phpcs-security-audit ergänzt mit weiteren Mustern. Danach folgt eine manuelle Durchsicht der kritischen Einstiegspunkte: alles, was Nutzereingaben verarbeitet, speichert oder ausgibt.

Sicherheit ist kein Feature, das man nachrüstet. Aber sie ist ein Risiko, das man systematisch reduzieren kann – auch in bestehendem Code.

Priorität nach Risiko

Nicht alle Schwachstellen sind gleich dringend. Ich priorisiere nach Exploitbarkeit und Schadenpotenzial: SQL-Injection in öffentlichen Formularen vor XSS in internen Admin-Bereichen. Datei-Uploads mit Ausführungspfad vor fehlenden CSRF-Tokens in Leseanfragen. Eine klare Priorisierung verhindert, dass das Team in endlosen Sicherheits-Backlogs versinkt und am Ende gar nichts behebt.

Fazit

Sicherheitsprobleme in Legacy-Code sind lösbar. Sie erfordern keine vollständige Neuentwicklung – sie erfordern Systematik. Wer die wichtigsten Schwachstellen kennt, die richtigen Tools einsetzt und nach Risiko priorisiert, kann ein altes System in vergleichsweise kurzer Zeit erheblich sicherer machen. Und dann darf man endlich aufhören, bei jedem Öffnen der Apache-Logs die Luft anzuhalten.