PHP Security – Der Stacktrace


In vielen PHP Content Management Systemen hat man das Problem das wegen Hooks oder Calls Methoden von Klassen nicht so gut abgeschirmt werden können wie man das gerne hätte. Eine erprobte und zuverlässige Methode Zugriffe zu prüfen ist dabei der wenig bekannte Stacktrace von PHP.

Hier liefert PHP den Stack aller Aufrufe zurück was zum einen viele Debug-Informationen liefert aber eben auch detailliert aufschlüsselt welche Datei / Funktion / Klasse oder Methode den Aufruf verursacht hat. Diese Funktion können wir uns zu nutze machen um das aufrufende Script z.B. gegen eine Whitelist zu verifizieren.

Das Beispiel liefert dabei folgendes Ergebnis:

Was genau wurde hier gemach?

Als erstes laden wir den Trace in die gleichnamige Variable. Das Binary Flag DEBUG_BACKTRACE_IGNORE_ARGS  dient dazu unnötige informationen nicht in den Trace zu laden.
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);

Anschließend speichern wir den normalisierten Document Root in die realDocRoot Variable
$realDocRoot = realpath($_SERVER['DOCUMENT_ROOT']);

Dann löschen wir den Document Root aus dem aktuellen __FILE__ Path
thisFile = str_replace($realDocRoot, '', __FILE__);

In der Schleife iterieren wir nun über das $trace  Array. Werte der Zeile speichern wir zur direkten Bearbeitung als Pointer in  &$value. Die $key  Zuweisung fügen wir zur Löschung ungewollter Einträge hinzu.
Da jede Zeile ein Array mit mehreren Werten ist, uns aber nur der Dateiname interessiert, laden wir diesen in die Variable und entfernen dabei gleich den Document Root.
$value = str_replace($realDocRoot, '', $value['file']);

Danach entfernen wir alle Zeilen die keine Datei haben also null oder ein Leerstring sind.
Ebenfalls entfernt werden alle Verweise auf die aktuelle Datei da wir diese automatisch freigeben möchten.

Zuletzt wird nach der schleife noch mit  unset($value);  der Pointer auf $value entfernt.

 

Jetzt enthält $trace  ein Array mit dem Trace aller Dateien die den Methoden Aufruf verursacht haben.
$lastTrace = array_shift($trace); pflückt uns somit das Script aus der Liste das unsere Methode aufgerufen hat.
Im Beispiel von oben war das „\wp-content\plugins\testplugin\testplugin.php“ welches wir über in_array($lastTrace, $whitelistArray) validieren und entsprechend reagieren können.

Haben sie Fragen oder Kommentare?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*