PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr

PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr (https://www.php-resource.de/forum/)
-   PHP Developer Forum (https://www.php-resource.de/forum/php-developer-forum/)
-   -   Download via header attachment... (https://www.php-resource.de/forum/php-developer-forum/76059-download-via-header-attachment.html)

nichtsooft 21-09-2006 16:40

Edit:
Zitat:

Original geschrieben von kuddeldaddeldu
...Es kann doch nicht so schwer sein, aus einem Pfad den Dateinamen zu lesen...
Ist es auch nicht! -> basename(). Aber ich durchschau nicht was du mir damit sagen willst? Wenn ich nur den Dateinamen ohne Pfad angebe, wird selbst PHP die Datei nicht finden!


Zur Codierung/Decodierung:
Nun ja; ich hab an und für sich mit htmlentities() und html_entity_decode() rumexperimentiert um das ganze URLgerecht zu machen.

Zur Überprüfung ob ein Pfad erlaubt ist:
Es sind grundsätzlich alle Dateien erlaubt, die im Verzeichniss "pics/galerie" abgelegt sind. d.h. wenn ich diesen String vor jede emfangene URL hänge kann der User eigentlich bloss noch erlaubte Dateien erreichen.

Punch me if I'm wrong!

TobiaZ 21-09-2006 16:43

NEIN.

Ein einfaches ../ reicht, um eine ebene Höher zu kommen. Das "Startverzeichnis"-setzen ist also keine Wirksame absicherung.

jahlives 21-09-2006 16:54

@topicstarter
Dateiname:
PHP-Code:

echo basename('irgendEinLanger/und/komplizierter/pfad/index.html'); 

Zitat:

Nun ja; ich hab an und für sich mit htmlentities() und html_entity_decode() rumexperimentiert um das ganze URLgerecht zu machen.
Würde ich jetzt urldecode() und urlencode() dazu verwenden...
Zitat:

wenn ich diesen String vor jede emfangene URL hänge kann der User eigentlich bloss noch erlaubte Dateien erreichen.
PHP-Code:

if(file_exists($_SERVER['DOCUMENT_ROOT'].'/pics/gallery/'.basename($_GET['datei']))){
    
//Datei ist im erlaubten Verzeichnis
}else{
    die(
'Diese Datei darf nicht runtergeladen werden. Und Tschüss');


Dann darfst du als Datei aber nur noch den Namen übergeben und nicht mehr den gesamten Pfad.
basename($_GET['datei']) sollte imho dafür sorgen dass nur der Dateiname verwendet wird und allfällige Pfadanhängsel abgeschnitten werden.

Gruss

tobi

kuddeldaddeldu 21-09-2006 17:04

Hi,

Zitat:

Aber ich durchschau nicht was du mir damit sagen willst? Wenn ich nur den Dateinamen ohne Pfad angebe, wird selbst PHP die Datei nicht finden!
Wenn ich Dich richtig verstanden habe, geht das Download-Fenster auf
und Du kannst die Datei abspeichern, blöd ist nur, dass er da so'n
komischen Namen vorschlägt?

Zitat:

Nun ja; ich hab an und für sich mit htmlentities() und html_entity_decode() rumexperimentiert um das ganze URLgerecht zu machen.
Dafür eignen sich eher URL-Funktionen.

Zitat:

Es sind grundsätzlich alle Dateien erlaubt, die im Verzeichniss "pics/galerie" abgelegt sind. d.h. wenn ich diesen String vor jede emfangene URL hänge kann der User eigentlich bloss noch erlaubte Dateien erreichen.
Wenn dieses Verzeichnis feststeht, warum übergibst Du dann
überhaupt Pfade? Dann übergib doch gleich nur die Namen und
bastel Dir für Dein readfile den Pfad davor. Hierbei trotzdem nicht
vergessen, den Namen zu überprüfen, s. Tobiaz!

Zitat:

Punch me if I'm wrong!
PATSCH!!! :D

nichtsooft 21-09-2006 17:05

@ jahlives

Von der Idee her garnicht schlecht!
PHP-Code:

if(file_exists($_SERVER['DOCUMENT_ROOT'].'/pics/gallery/'.basename($_GET['datei']))){
    
//Datei ist im erlaubten Verzeichnis
}else{
    die(
'Diese Datei darf nicht runtergeladen werden. Und Tschüss');


Aber was wenn die Datei in einem Subverzeichniss liegt? Bsp:
/pics/gallery/bla/bla/blub/bild.jpg

3DMax 21-09-2006 17:11

Zitat:

Original geschrieben von nichtsooft
Aber was wenn die Datei in einem Subverzeichniss liegt? Bsp:
/pics/gallery/bla/bla/blub/bild.jpg [/B]
dann kannst du ja mit realpath() den kompletten pfad bilden und dann überprüfen, ob er mit /pics/gallery beginnt.

nichtsooft 22-09-2006 11:36

NÖ Leute ich steig da absolut nicht durch! Sitze jetzt länger als nen Tag dahinter und schaff's nicht! Bin müde und geh jetzt schlafen!

Jmd ne idee ob man sowas als snippet irgendwo im web bekommt?

kuddeldaddeldu 22-09-2006 15:50

Hi,
Zitat:

Jmd ne idee ob man sowas als snippet irgendwo im web bekommt?
Nö.

Das halte ich aber auch nicht für nötig. Du bist doch eigentlich fast am
Ziel. Wenn Du Hilfe willst, musst Du uns aber genau sagen, womit Du
nicht klarkommst. Hast Du ein Problem mit der Überprüfung des
Verzeichnisses? Wenn ja welches? Mach Testausgaben Deiner
Variablen.
Stört Dich der komische Dateiname? Setze in der entsprechenden
Header-Zeile (Content-Disposition...) filename auf den Dateinamen,
nicht auf den Pfad (ich fände es übrigens EAB, wenn mir als Download-
Name ein Pfad vorgeschlagen wird. Der wird auf meinem Rechner
selten existieren, und wenn, will ich das da aber vielleicht gar nicht rein haben).

Zitat:

NÖ Leute ich steig da absolut nicht durch! Sitze jetzt länger als nen Tag dahinter und schaff's nicht! Bin müde und geh jetzt schlafen!
Guts Nächtle ;)

nichtsooft 22-09-2006 18:17

Nunja; womit ich nicht klar gekommen bin und was ich selbst jetzt nach langem Schlafe nicht durchblicke ist folgendes:

Ich sende eine Variable per URL and die download.php

die sieht so aus:

download.php?file=Ppl/bahnengolf/Herzogenburg07_2006/IMG_0165.JPG

da hol ich mir dann in der Datei per basename() den Dateinamen raus und füge den in den Header-befehl ein:
PHP-Code:

$dlfl basename($_GET[file]);

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

Logischerweise kennt sich das downloadscript jetzt absolut nicht mehr aus, weil es ja nicht weiss in welchem Verzeichniss die Datei "IMG_0165.JPG" liegt und wie mir ja schon mehrmals gesagt wurde, darf ich aber keinen Verzeichnisspfad in den Header schreiben! :(

Was die Verzeichniss- und Dateisicherheit angeht; So weit bin ich noch nichtmal gekommen! :dontknow:

Es ist schon schlimm dumm zu sein, aber wenigstens tut's nicht weh! *gg*

jahlives 22-09-2006 18:33

Dein Header Befehl würde aber einen Download verursachen und nicht die direkte Anzeige im Browser.
Und wieso kennst du den Pfad nicht ? Den haste ja immer noch in $_GET['file']. Aber wenn das Download Script direkt im Verzeichnis mit den Bildern liegt, dann brauchst du keinen kompletten Pfad sondern es reicht der Dateiname, weil PHP diesen Pfad dann als relativ betrachtet und das File im Verzeichnis sucht wo auch die PHP Datei liegt.
PHP-Code:

header("Content-type: image/jpg");
header("Content-disposition: inline; filename=$dlfl"); 

Müsste die Anzeige des Bildes erzwingen. Deine Version würde afaik erst einen Download erzwingen.

nichtsooft 22-09-2006 18:39

...würde einen Download erzwingen....
Darum heisst's ja auch "download.php" ;)
Und wenn man dann noch die vorangegangenen Posts gelesen hat weiss man auch, dass die download.php nicht im Verzeichniss mit den Bildern ist.
Genau das ist ja das Problem! :motz:

Edit: Wenn jmd nen Blick drauf werfen will: LINK zum Projekt

jahlives 22-09-2006 18:46

Zitat:

Und wenn man dann noch die vorangegangenen Posts gelesen hat weiss man auch, dass die download.php nicht im Verzeichniss mit den Bildern ist.
Sorry zu wenig genau gelesen. In diesem Falle brauchst du den Pfad um readfile() mitzuteilen welches Bild ausgelesen werden soll.
In den Header brauchst du aber den Pfad nicht, da geht's nur um den Namen mit dem das Bild beim Client gespeichert werden soll. Da kannst du schreiben was du willst...
Wenn ich auf deinen Link klicke und das Bild öffnen will, kann der Typ nicht bestimmt werden. Also fehlt dir ggf ein
PHP-Code:

header("Content-type: image/jpg"); 

Gruss

tobi

nichtsooft 22-09-2006 18:52

hmm...? Hab ich eigentlich eingebaut! :confused:

Aktuell:
PHP-Code:

<?php

// declare the basic directory for security reasons
// Please do NOT attach a "/"-suffix !
$dlfl basename($_GET[file]);
$basedir 'pics/galerie';
// $diradd = trim($path_parts['dirname'], $basedir);


////////// SECURITY
// compare the entered path with the basedir
// $path_parts = pathinfo($_REQUEST['file']);
// if ($diradd != 0) {
// ANTI-CRACK-ATTEMPT
//   echo $_REQUEST['file'].'<br>';
//   echo $path_parts['dirname'].'<br>';
//   die ('coding good - h4x1ng bad!');}


// $datei = $_GET[file];
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Description: File Transfer");
header("Content-type: image/jpg");
header("Content-Disposition: attachment; filename=$dlfl");
header("Content-Transfer-Encoding: binary");
readfile($datei);
?>


kuddeldaddeldu 22-09-2006 18:55

Hi, gut geschlafen?

Jetzt verstehe ich, was Dein Problem ist:
Du verwechselst da etwas entscheidendes. Diese Header, die Du da
setzt, sind Response-Header. In einfachen Worten: Das sind Informationen,
die der Browser auswertet, um zu wissen, was er mit dem Content ,
der danach kommt, anstellen soll/kann. Diesen Content lieferst Du doch
schon mit Deinem readfile. Der Name, den Du da in dem Header einträgst,
ist nur ein Vorschlag für einen Namen. Stell Dir vor, Du klickst irgendwo
auf einen Download, ein Fenster geht auf, wo Du auswählen kannst,
wohin Du das speichern willst. Jetzt findest Du den vorgeschlagenen
Namen "steigerungsfähig" und änderst den. Meinst Du, der Download
funktioniert dann nicht? Du könntest das auch leer lassen, dann würde
da download.php oder download.html erscheinen.
Also, um es kurz zu machen:
In dem Header den Dateinamen setzen und dann
readfile(dateipfad).

So, und nun probier das einfach mal aus. Die Pfadüberprüfung sollte
sich dann nicht mehr so schwierig gestalten.

LG

nichtsooft 22-09-2006 18:59

*looool*

Soll's das wirklich gewesen sein!? *dasKeyboardMitVielSchwungAufMeineHohlbirneSchmetter*
Muss ich gleich mal versuchen! *kopfschüttel*

Naja: Wie gesagt: ...wenigstens tut's nicht weh!


Alle Zeitangaben in WEZ +2. Es ist jetzt 12:10 Uhr.

Powered by vBulletin® Version 3.8.2 (Deutsch)
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0
[c] ebiz-consult GmbH & Co. KG