Verschleierter Download mit PHP

Eine Anforderung für ein kleines Webprojekt war der Download von Dateien, mit der Besonderheit, dass diese nicht so einfach für jeden Nutzer downloadbar sein sollen, sondern lediglich nach einem Kauf über Digistore24. Hierfür müssen die Dateien grundsätzlich schon für jeden Seitenbenutzer verfügbar sein, ansonsten funktioniert dieses Vorgehen nicht mit Digistore24 und man müsste die Dateien dort kostenpflichtig in einen Download-Tresor ablegen. Anstatt die Dateien aber all zu einfach verfügbar zu machen, z. B. in dem man sie unter www.domain.de/download/Produkt1.zip ablegt, kann man den Download mit kryptischen Links verschleiern. Diese kann man dann auch von Zeit zu Zeit austauschen.

Es gibt verschiedene Funktionen mit denen man einen Datei-Download unter PHP realisieren kann, z. B. die folgenden:

Bevor mit einer der zuvor gezeigten Varianten die Ausgabe der Datei beginnt, gibt man noch einen Header mit PHP aus. Darüber lässt sich z. B. wunderbar der Dateiname für die herunter zu ladende Datei definieren:

Die herunter zu ladenden Dateien legt man in ein per .htaccess geschütztes Verzeichnis. So kann nur das PHP-Skript die Dateien erreichen.

Der PHP-Datei gibt man nun einen kryptischen Namen, wie beispielsweise aewqc6qg3qzvgunbr5j7.php. Dadurch alleine hat man aber noch keine brauchbare Verschleierung der Download-Adresse erreicht, denn man hätte die Zip-Datei auch einfach aewqc6qg3qzvgunbr5j7.zip nennen können. Allerdings sähe dies, für den Benutzer der die Datei herunterlädt, dann blöd aus, da die Datei nach dem beendeten Download auch so heißen würde.

Die eigentliche Verschleierung kommt durch die Verwendung eines GET-Parameters, der beim Aufruf des Skriptes angehangen sein muss:

Somit wird im Beispiel erst bei Aufruf der URL www.domain.de/aewqc6qg3qzvgunbr5j7.php?key=dTTC57Bb9kYCracZmDmP der Download der Datei gestartet. Auf diese Weise lässt sich das Skript auch direkt für den Download verschiedener Dateien nutzen, die dann anhand des angehangenen Keys ausgesucht werden.

Zur Sicherheit habe ich noch folgendes an den Anfang des Skriptes gesetzt, da ich Probleme mit dem Output-Buffer bekam, den der Rest der Seite nutzt. Außerdem sollte der GET-Parameter nicht einfach so weitergereicht werden, wobei wir ja eine Prüfung auf genau einen Wert machen und eine Code-Injection eigentlich schwer möglich sein sollte. Aber man weiß ja nie.

Da der Käufer zuvor eine Dankesseite mit dem Download-Link angezeigt bekommen soll, erstellt man hierfür ebenfalls eine PHP-Datei mit einem kryptischen Namen mit dem gleichen Aufbau, welche beim Aufruf mit dem entsprechenden GET-Parameter dann den HTML-Code mit dem passenden Download-Link ausgibt. Diese URL, beispielsweise  www.domain.de/jksdfh37845hdjksfz3478uhf.php?key=KsdfsdfLH645IsdfUEF347 , hinterlegt man dann im Backend bei Digistore24 oder einer anderen Vertriebslösung für digitale Produkte als Dankesseite.

Hier ist noch eine übersichtliche Darstellung des genauen Ablaufs der beiden Skripte:

 

 

Problem:

Das Download-Skript an sich funktionierte und tat genau das was es soll. Allerdings kam es beim ausführlichen Testen dann zu einem sehr unschönen Problem. Bis zu einer Dateigröße von 50 MB schien es keine Beeinträchtigung zu geben. Folgendes Problem taucht dann beim Download großer Dateien auf:

Sobald der Download gestartet wurde, war ein Surfen auf der Webseite über die gleiche Internet-Leitung nicht mehr möglich! Über einen anderen Anschluss allerdings schon. Der Webserver war also zum Glück nicht komplett ausgelastet, allerdings verweigert er wohl eine Zuweisung von mehr Verbindungen an den gleichen Benutzer bzw. dessen IP. Da es sich um Shared Webhosting von All-Inkl handelt fällt eine tiefgehndere Analyse des Problems auch aus.

 

Lösung:

Die einzige brauchbare Lösung, die mir nach Stunden in den Sinn kam, war es, eine unabhängige Subdomain für den Datei-Download zu nutzen.

Unter der Subdoamin downloads.domain.de liegt nun das Downloadskript und ein leeres index.html-File, sowie natürlich die bereit zu stellenden Dateien im per .htaccess geschützten Ordner für den Download. Durch diese Auslagerung ist nun die Haupt-Domain problemlos nutzbar, selbst während mehrere Downloads von einem Anschluss über die Subdomain laufen. Dies beeinträchtigt nicht die Verbindungen zur Haupt-Domain. Da auf der Subdomain keine Seite zum Anzeigen liegt, ist diese Beeinträchtigung für die Subdomain nicht von Bedeutung.

http://www.sitepoint.com/forums/showthread.php?481659-file-download-problem-using-readfile()

Tobias Langner

Ich arbeite seit mehreren Jahren als IT-Administrator, bin ausgebildeter Fachinformatiker für Systemintegration und Studium-„Pausierer“ an der FernUni Hagen

Achtung: Für die Richtigkeit der zur Verfügung gestellten Informationen, Skripte, etc. übernehme ich keine Gewähr. Deren Nutzung geschieht ausdrücklich auf eigene Gefahr!

Schreibe einen Kommentar