PHP Verzeichnis Übergabe prüfen

Ich muss in meinem Plugin für WordPress den ABSPATH übergeben um eine eigene Ajax Behandlung zu haben.
Was meint ihr ist der Code schnipsel dafür geeignet um es möglicht sicher gegen Angriffe zu machen ?

if ( is_file( dirname(dirname(dirname(dirname( __FILE__ )))).'/wp-load.php' ) ) {
require_once(dirname(dirname(dirname(dirname( __FILE__ )))).'/wp-load.php');
} else {
$abspath = filter_input( INPUT_POST, 'ABSPATH', FILTER_SANITIZE_URL );
$abspath = rtrim(realpath($abspath), '/\' );
if ( ! empty($abspath) && is_dir( $abspath . '/' ) && is_file( realpath( $abspath . '/wp-load.php' ) ) ) {
require_once($abspath . '/wp-load.php');
} else {
die();
}
}

Erläuterung:
Wenn der Plugins Ordner im Standard Verzeichnis ist oder zumindest in der selben Verzeichnis Tiefe muss die Übergabe nicht genutzt werden.
Sonst.
Das übergebene Verzeichnis vorfiltern (nur in URLs erlaubte Zeichen werden zugelassen)
mit ‘realpath()’ alle ‘../’,’./’ entfernen und prüfen ob das Verzeichnis existiert.
da ‘realpath()’ auch das aktuelle Verzeichnis ausgibt nochmal Verzeichnis und Datei auf Existenz prüfen.
WP-load.php laden.

2 Gedanken zu „PHP Verzeichnis Übergabe prüfen

  1. Ralf

    Das dirname-gerammel führt früher oder später zu Problemen. Du weißt ja nicht ob die Datei wp-load.php auf die du mit den dirname-gerammel zeigst auch die wp-load.php ist, die du suchst. Ändert jemand die Verzeichnisstruktur in seinem Blog, legt z.B. wp-content auf eine Subdomain (wpcontent.example.org/my/mighty/wordpress/wp-content/plugins/), schlägt die Prüfung fehl. Es würde also reichen wenn auf der Subdomain zufällig an der Stelle auf der dein dirname-gerammel zeigt eine wp-load.php liegt (Backup, Überbleibsel aus einer anderen Installation) und schon hast du die falsche wp-load.php inkl. defektem ABSPATH.

    ABSPATH wird in wp-load definiert. Also ABSPATH_POST aus dem POST-Array fischen, wp-load mit include ABSPATH_POST . 'wp-load.php'; includieren und vergleichen ob ABSPATH_POST gleich ist ABSPATH: if( defined( 'ABSPATH' ) && ABSPATH == ABSPATH_POST ) {...}. Oder auf Ungleichheit hin prüfen: if( ! defined( 'ABSPATH' ) || ABSPATH != ABSPATH_POST ){ die() }
    Damit kannste schon mal relativ sicher sein das du die wp-load.php geladen hast, die du suchst.

    Die totale Sicherheit ist das jedoch nicht. Jemand könnte das POST-Array manipulieren und ABSPATH_POST woanders hin zeigen lassen wo eine manipulierte wp-load.php liegt.
    Bleibt dir noch die Möglichkeit ABSPATH in eine Session-Variable abzulegen. Das ist der übliche Weg wie man Variablen zwischen zwei Scriptaufrufen (Seitenaufrufen) übergibt. Sessions sollten eigentlich von allen Servern unterstützt werden.
    Sollte dies aus irgend einen Grund nicht der Fall sein, bleibt dir als letzter Ausweg noch ABSPATH in einem Cookie zu speichern. Das würde ich aber niemalsnicht machen. Cookies können vom Benutzer gesperrt sein, können relativ einfach manipuliert werden und sind dafür nicht gemacht (sind arg langsam).

    Also:
    - ABSPATH in einer Session-Variablen speichern
    - ABSPATH im POST-Array übergeben

    Im Ajax dann:
    -ABSPATH_POST und ABSPATH_SESSION aus dem POST-Array bzw. den Session-Variablen fischen.
    - Prüfen ob die beiden gesetzt sind
    - Ggf. Maßnahmen wenn eins von beiden/beide nicht gesetzt ist
    - wp-load.php includieren
    - Prüfen ob ABSPATH mit ABSPATH_POST und/oder ABSPATH_SESSION übereinstimmt.

    Antworten
    1. Daniel Hüsken Artikelautor

      danke für die Antwort.

      Ich habe natürlich der sicherheit halber noch eine nonce mit eingebaut die nach dem include auch noch geprüft wird.

      Den abspaht vergleichen werde ich zu sichert auch noch mit einbauen.

      Leider kann ich die variante mit den Sessions nicht uneingeschränkt nutzen da ich auch ein Script habe welches direkt aufrufbar sein soll.

      Antworten

Hinterlasse eine Antwort

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

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>