Zum Inhalt springen

Sicheren Download realisieren


Empfohlene Beiträge

Moin,

nachdem ich nun mein Problem mit den Variablen und der POST Methode beseitigt habe, habe ich schon die nächste Frage :-))

Ich möchte folgendes realisieren, aber komme im Augenblick nicht so richtig auf eine Lösung. Dies möchte ich erreichen:

Ein Kunde loggt sich ein. Ist der Login erfolgreich, wird eine Tabelle abgefragt, welche Informationen für Ihn vorliegen. In dieser Tabelle sind u.a. auch Dateinamen abgelegt, die zu einer Datei auf dem Webserver gehören. In der Liste, die der Kunde angezeigt bekommen, werden u.a. auch diese Daten in Form eines Hyperlinks zum Download angeboten. Damit habe ich aber nun folgendes Problem.

Über die Statusleiste kann der Kunde den genauen Pfad zu Datei erkennen. Sicherlich kann ich diese Leise ausblenden, aber dann wäre der Pfad immernoch im Quelltext lesbar. Nun kann ein cleverer Kunde versuchen, wenn er sich eingeloggt hat, den Hyperlink in die Adressleiste einzutragen und den Dateinamen abzuendern, um somit auf das Verzeichnis und die Daten eines anderen zuzugreifen.

Ich könnte mir vorstellen, das man das vielleicht mit einem weiteren PHP-Script sicherer machen könnte. Dieses Script würde dann zunächst hinter dem Hyperlink hinterlegt (mit Dateinamen, Benutzer, Passwort) ... dieses Script prüft dann nochmal Name und Passwort und ob die Person auf die Datei zugreifen darf und führt dann den Download durch. Diese Lösung wäre für mich natürlich besser als bloss den Datei-Hyperlink zu hinterlegen ... aber kann zufrieden bin ich noch nicht.

Gibt es vielleicht elegantere Lösungen? Wiedermal bin ich für Hinweise sehr dankbar. Achja ... bei Lösungen bitte auch konkrete Lösungsansätze nennen ... ich entwickel nämlich nicht täglich in PHP und habe somit natürlich nicht das Know-How eines PHP-Freaks ;-) *noch nicht jedenfalls* :D

Gruss Metaner

Link zu diesem Kommentar
Auf anderen Seiten teilen

http://www.php.net/manual/de/function.header.php durchlesen (auch die Kommentare), dann ein Script bauen was nur den Dateinamen als Parameter übergeben bekommt (oder sonstwas, bleibt Dir überlassen) und dann einen Header sendet, der die entsprechende Datei zum Download anbietet.

Heißer Tipp:

header("Content-Type: application/mp3");

header("Content-Disposition: attachment;filename=$mp3");

Link zu diesem Kommentar
Auf anderen Seiten teilen

Vielen Dank für den guten Hinweis ... Habe nun in mein Script diese Funktion eingebaut.

Original geschrieben von Valium

header("Content-Disposition: attachment;filename=$mp3");

Nun habe ich aber noch ein kleines/grosses Problem. Dieser Aufruf funktioniert zwar immer, aber die richtige Datei lässt sich nur downloaden wenn die Datei im selben Verzeichnis wie das Script ist. Pfad- und Laufwerksangaben werden gnadenlos irgnoriert. Habe auch mal die RFCs angesehen ... konnte da auch nichts zu finden.

Wie kann ich also einen Verweis auf eine Datei setzen die sich an einer anderen Stelle auf dem Server befindet?

Schonmal vielen Dank im voraus für Deine Hilfe.

Gruss Metaner

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wie kann ich also einen Verweis auf eine Datei setzen die sich an einer anderen Stelle auf dem Server befindet?

hi,

probier's mal so.


// gibt den typ der datei an
header("Content-Type: application/mp3");
// gibt die position der datei an
header("Location: http://www.deinedomain.de/".$file);[/PHP]

bei mir funktioniert das sehr gut.

ciao TinTin

Link zu diesem Kommentar
Auf anderen Seiten teilen

@TinTin

Dein Vorschlag kommt leider in meinem Fall nicht in Frage. Wie ich in meinem ersten Posting geschrieben hatte, muss es eine Möglichkeit sein, durch die der Link zur Datei dem Anwender verborgen bleibt.

Wenn ich das Problem mit Location löse, habe ich zwei Nachteile. Erstens wird der Link zur Datei in der Adressleiste eingeblendet und die aktuelle Internetseite verschwindet (oder es öffnet sich ein neues Fenster ... was ich auch nicht möchte).

Hat jemand noch eine Idee für mein Problem?

Gruss Metaner

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

wenn du auf jedenfall verhindern willst dass der User die URL sieht bleibt dir nicht viel anderes uebrig als mit einem Script die Datei zu oeffnen, den Inhalt auszulesen, einen entsprechenden Header zu senden und danach den Dateiinhalt auszugeben. So sieht der User nur die URL des Download-Scripts, dafuer geht das ganze bei groesseren Dateien natuerlich deutlich auf die Performance.

Michael

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo metaner!

Im genannten Fall von tintin ist die url nicht im HTML-Source ersichtlich. Lediglich wenn der User authentifiziert ist und somit ein Download gestattet ist, wird der Ort der Datei per Header an den Browser(User) mitgeteilt. Das ganze spielt sich aber im PHP-Skript ab, davon steht nichts im HTML - Source.

Natürlich kann jeder, der den Link kennt, die Datei ziehen.

Das könnte man dann jedoch noch mit htaccess lösen.

Wie das im Detail aussieht, kann ich dir aber nicht auf die Schnelle sagen.

cu

Link zu diesem Kommentar
Auf anderen Seiten teilen

Vielen Dank für Eure Hilfe. Der Tipp von Jaraz war genau das was ich gesucht habe. Nun läuft alles 1a ... so wie ich es mir vorgestellt hatte ... mit Session und so sicher, das niemand dahinter kommt wo auf dem Server die Daten liegen :-)) *freu*

@Jaraz ... FAQ schön und gut ... aber leider gibts davon nicht gerade wenige :D

Ausserdem bin ich kein PHP Fachmann ... mein Fachgebiet sind Datenbanken und OOP :-))

Gruss Metaner

Link zu diesem Kommentar
Auf anderen Seiten teilen

Original geschrieben von Metaner

@Jaraz ... FAQ schön und gut ... aber leider gibts davon nicht gerade wenige

Also ich kenne nur eine deutschsprachige FAQ für PHP :D

Außerdem schicke ich deswegen ja immer den genauen Link mit und schreibe nicht einfach RTFM oder RTFFAQ. :D

Gruß Jaraz

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 7 Jahre später...

Yes ich darf einen 7 Jahre alten Thread ausgraben ohne Ihn zu schänden :D

Im Ernst ich habe im Prinzip dasselbe Problem, allerdings in dahingehend verschärfter Form, dass es auf keine(!) Art und Weise möglich sein darf einen Download zu starten, wenn ich nicht zuvor am System authentifiziert worden bin.

Aktuell ist das ganze per .htaccess gelöst.

Sollziel ist es, dass dem User genau die Dateien angezeigt werden, die er Downloaden kann und darf.

Authentifizierung erfolgt zuvor via Webformular. Userdaten liegen inkl. md5(passwort) in einer MySQL.

Meine Ideen dazu:

(1) In dem Moment wo der User sich einloggt werden die Dateien von einem Verzeichnis, welches ausserhalb vom Webverzeichnis liegt in ein nur während die Usersession aktiv ist verfügbares Verzeichnis kopiert.

Da sehe ich aber nur Nachteile. Zum einen Reden wir von Files, die gut und gern mal ein paar Gbyte haben können und zum anderen wäre es dann möglich unter kenntnis des Pfads die Datei runterzuladen, obwohl ich nicht der User dieser Session bin

(2) In dem Moment wo der User auf den Downloadlink klickt wird genau diese Datei per header Redirection gesendet.

Nachteil: Datei muss in einem Verzeichnis liegen, welches per PHP lesbar ist. Theoretisch wäre durch Manipulation der übergebenen Post Variable also wieder jedes File erreichbar.

(3) Die Variante gefällt mir aktuell noch am besten:

PHP: Case 3: setting doc_root or user_dir - Manual

Allerdings muss ich zugeben, dass ich das noch nicht ganz verstanden habe.

Verstehe ich das richtig, dass ich basierend auf einer bestehenden Usersession (aka Session ID vorhanden und konkret einem User zugeordnet) ein "user_dir" setzen kann, welches dann ausschliesslich von diesem (der Session zugeordneten) User erreichbar ist?

Hat da jemand ein Beispielcodeschnipselchen?

Wenn noch jemand andere Ideen hat, immer her damit. Hier nochmal die Infos:

- Userverwaltung basierend auf Usernamen/Passwort in MySQL DB

- Sessions werden verwendet; Cookies sind soweit nötig auch kein Thema (aus Sicherheitsgründen aber eher schwierig, da fälschbar)

- Jedem User soll genau ein Ordner mit verschiedenen .tar.gz Files zur Verfügung stehen

- Kein User soll auf einen Ordner eines anderen Benutzers zugreifen können. Egal wie

- Ordnergrösse liegt teilweise jenseits von 10gbyte

- Betriebssystem / Server: SLES 10.1 ; Apache 2.2 ; PhP 5.2 ; MySQL 5.0.21

So und nu Feuer frei, wenn noch Infos fehlen, her mit den Fragen :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Der User kann ja den link der Ordner / Dateien nur rausbekommen wenn du ihm die irgendwie darstellst

wenn du also den Download ueber

www.domain.de/download.php?datei=bsp.tar.gz

realsieren wuerdest, kommt der User zumindest erst einmal nicht darauf wo die Dateien liegen.

in der download.php kannst du ja dann noch mal abfragen ob der user auf die datei berechtigung hat usw.

dann solltest du natuerlich die ordner soweit schuetzen, am besten so das man nur ueber dein script darauf zugreifen kann, aber dafuer kenn ich mich zu wenig mit .htaccess aus um dir da genaueres zu sagen.

Ted

Link zu diesem Kommentar
Auf anderen Seiten teilen

Es reicht einfaches Try and Error um nen Pfad und ne Datei rauszubekommen, sofern diese "einfach so" übers Web erreichbar sind.

Gut klar, ich könnte entsprechend wenig sprechende Pfade verwenden, aber das ist nicht die Art von Sicherheit die mir (und meinen Kunden) vorschwebt ;)

Eingefallen ist mir grad noch, dass man ggfl. .htaccess und den Login via Webformular koppeln könnte.

Ideen dazu:

(1)

.htaccess ohne Login == Zugriff verboten

.htaccess bei Login == Zugriff erlaubt für User xyz

User xyz speicher ich mir beim Login in einer Session Variablen

Nun muss ich nur noch dafür sorgen, dass bei Aufruf von /pfad/datei.tar.gz auch der richtige Authenticated User gesendet wird. Geht das?

(2) Kann eine .htaccess statt einer .htpasswd auch eine SQL DB abfragen um "Valid User" zu bekommen?

Ich muss da glaub ich mich auch nochmal mit .htaccess mehr auseinandersetzen :D

Aber die generelle Idee in dieser Richtung gefällt mir schonmal :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

du koenntest doch den Zugriff durch .htaccess generell verbieten und nur fuer den localhost erlauben.

Dies stellt sicher das nur durch dein script darauf zugegriffen werden kann, welches ja dann alle prüfungen und so uebernehmen kann

Link zu diesem Kommentar
Auf anderen Seiten teilen

du koenntest doch den Zugriff durch .htaccess generell verbieten und nur fuer den localhost erlauben.

Das Skript greift doch nicht per http auf die Dateien zu..

Wo ist denn jetzt das Problem? Es wurde doch alles erklärt..

1. Downloadbare Dateien an einem Ort speichern, der per http nicht erreichbar ist (Über documentRoot oder per .htaccess)

2. Die downloads laufen über ein PHP-Skript, das mit readfile o. ä. den Inhalt der runter zu ladenden Datei ausliest und an den Browser weitergibt. In dieses Skript muss dann natürlich noch rein, ob der Benutzer die angeforderte Datei überhaupt runterladen darf. Aufruf wäre - wie schon oben beschrieben - etwas so: download.php?file=dateiname.

Um das ganze zu verkomplizieren, kann jeder Dateiname mit einem Hash verknüpft werden, der aus der DB ausgelesen wird.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 Monate später...

Moin,

muss das leider noch mal rauskramen.oO

Prinzipiell funktioniert das System wie gewünscht:

1. Login via html Formular inkl. session_start() und reauthentifizierung auf Cookie Basis, sofern noch vorhanden

2. Zugriff auf den kundenspezifischen Downloadordner ohne, dass dieser irgendwo innerhalb vom Apache DocumentRoot oder via Alias erreichbar wäre. Sprich selbst wenn jemand wüsste wo genau im Filesystem die Daten liegen, kommt er da nicht direkt über den Webserver heran.

Realisiert ist der eigentliche Download so, dass ich die Datei über das Filesystem einlese und dann via Apache zum User schicke. Die eigentliche Funktion hierfür:


function GetFile($path, $filename, $mimeType='application/octet-stream'){
session_write_close();
set_time_limit(0);

//required, or it might try to send the serving //document instead of the file
header("Cache-Control: ");
header("Pragma: ");
header("Content-Type: $mimeType");
header("Content-Length: " .get_file_size($path."/".$filename) );
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary\n");

if($file = fopen($path."/".$filename, 'rb')){
while( (!feof($file)) && (connection_status()==0) ){
print(fread($file, 1024*8));
flush();
}
fclose($file);
}
return((connection_status()==0) and !connection_aborted());

[/php]

An und für sich also recht simpel.. Das Problem was ich nun aber habe, ist dass ich teils recht große Dateien (teils weit jenseits von 2gbyte) habe und der Apache sich dabei massiv Arbeitsspeicher genehmigt. Das zugrundeliegende Debian System hat 2gbyte RAM und 12gbyte Swap Space.

6-7 parallele Downloads sind je nach Dateigrösse grad noch drin, aber dabei ist das System schon massiv am swappen.

Da das ganze aber im Endausbau etwa 100 parallele Downloads bearbeiten soll, wird das so nix. Jedenfalls nicht, wenn ich das Ganze einfach durch einen massiven RAM Ausbau erschlage...

Jemand eine Idee, wie man den Speicherkonsum eindämmen kann? Ich hab da einige Ideen, aber ich will jetzt erstmal noch keinen in eine bestimmte Richtung lenken, sondern erstmal nur Ansätze und Ideen sammeln ...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...