dedlfix: Bilder in zugriffsverweigerndem Ordner auslesen

Beitrag lesen

Tach!

--- PROBLEMSTELLUNG ---

Gegeben sind eine PHP-Datei, die auf JPEGs, die in einem zugriffverweigernden Ordner (htaccess: Require all denied) liegen, zugreifen soll. (Die PHP-Datei selbst liegt außerhalb des Ordners.)

Das funktioniert natürlich mit

<?php
$img = imagecreatefromjpeg("PFAD-ZUR-JPEG-DATEI");
imagejpeg($img, "neuer_name.php");
imagedestroy($img);
?>
<img src="neuer_name.php">

...logischerweise wird dadurch aber eine NEUE php-Datei (neuer_name.php) auf dem Server erzeugt, was natürlich nicht Sinn und Zweck der Sache ist.

Du mischst hier zwei Dinge. Der Verweis auf eine Bild-Resource steht im HTML-Code der Response des einen Requests. Der Request nach dem Bild ist dann ein zweiter Request. Du braucht und solltest das Bild nicht in dem ersten Request bearbeiten oder bereitstellen.

Wie lese ich also via PHP die JPEGs, die sich im zugriffsverweigernden Ordner befinden aus, ohne dabei neue Dateien zu erstellen?

Deine Verweise sollten nicht auf Bilddateien gehen, sondern auf ein neu zu schreibendes Script. Dieses muss als Parameter den Namen der Bilddatei übergeben bekommen. Alternativ kann man das auch im Apachen mittels Rewrite so gestalten, dass der Bild-Request auf das Bild-Auslieferunggsscript geleitet wird, inklusive Übergabe des angefragten Namens - oder man holt ihn sich aus einem der $_SERVER-Einträge.

Das Auslieferungsscript prüft nun, ob der Request auch im vorgegebenen Verzeichnis bleibt oder jemand es missbraucht, um irgendwo anders zu wildern. Dazu verknüpft man den Dateinamen aus dem Request mit dem Verzeichnis, schickt das dann durch realpath() und vergleicht, dass der Anfang mit dem Pfad zum Bildverzeichnis übereinstimmt. Falls jemand nach ../../darfstenicht fragt, kommt ein anderer Wert raus.

Gegebenenfalls kommen noch weitere Prüfungen gemäß deiner Geschäftslogik dazu. Wenn alles gut ist, sendest du einen passenden Content-Type-Header und nimmst dann readfile() zum Ausliefern der Datei. imagejpeg() und Konsorten brauchst du nur, wenn die Grafik noch bearbeitet werden muss. In dem Fall ruft man dann am Ende imagejpeg() ohne Dateinamen auf, wodurch die Grafik lediglich aus dem Speicher gesendet wird, ohne eine Datei anzulegen.

dedlfix.