[PHP] Files voor download aanbieden

Pagina: 1
Acties:
  • 154 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hoi,

via het volgende php scriptje, dat ik download.php heb gedoopt, probeer ik een file voor download aan te bieden. Dit scriptje start zodra iemand ergens op klikt en er opent zich dan een save-as window. Zoals wel te verwachten was reageert niet elke browser hetzelfde. IE users krijgen in plaats van $file als gesuggereerde filenaam 'download' te zien. Opera 6+ en Netscape 7 users zien 'download.php', dus de naam van het script. M.a.w. zo'n beetje elke browser (behalve nescape 4.7) negeert de regel header("Content-Disposition:attachment;filename=$file") en maakt er maar wat van.

<?
$file= getenv("QUERY_STRING");
$document_root=getenv("DOCUMENT_ROOT");
if($fp=fopen($document_root.$file,"r"))
{
// $size = filesize($fp);
header("Content-type:application/download");
header("Content-Disposition:attachment;filename=$file");
// header("Content-Length: $size");
header("Pragma: no-cache");
header("Expires: 0");
@fpassthru($fp);
}
else
{
echo $document_root . $file . "not found";
}
?>

De file size heb ik ff tot commentaar gemaakt want die zorgt ook voor ellende. Het lijkt wel of op de hele header conventie vreemd gereageerd wordt. Wie weet raad?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik ben wat vergeten toe te voegen. Ik weet dat een simpele link plaatsen het ook mogelijk maakt een file te downloaden. Trust me, er is een reden voor dat dit met een apart scriptje gebeurt. En dat zou ook moeten kunnen, ljikt me. Maar wat zit er dan fout bij deze 1e versie?

Acties:
  • 0 Henk 'm!

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 17:06

gorgi_19

Kruimeltjes zijn weer op :9

Download scripts zijn wdb een bende. Mede door een bug in IE5 moet je afaik de browser controleren en de header hierbij aanpassen. Zie oa http://support.microsoft....kb/articles/q182/3/15.asp

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Acties:
  • 0 Henk 'm!

  • Sponge
  • Registratie: Januari 2002
  • Laatst online: 10-09 12:16

Sponge

Serious Game Developer

Hmm, misschien een stom idee, maar is een redirect naar de file geen optie? Werkt voor m'n loadbalancer perfect :).

Overigens heb ik niet echt een idee wat het browser probleem betreft...

[ Voor 27% gewijzigd door Sponge op 07-03-2003 14:57 ]


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Over het algemeen wil je bij files die je ter download aanbied via een script de bezoeker ergens toe verplichten. Als je simpelweg redirect naar een file, kan de url achterhaald worden, en kan iedereen leechen wat hij wil. Ik neem aan dat dat ook de overweging is van de topicstarter :)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • bgever
  • Registratie: April 2002
  • Laatst online: 28-05-2021
drm schreef op 07 maart 2003 @ 15:04:
... Als je simpelweg redirect naar een file, kan de url achterhaald worden, en kan iedereen leechen wat hij wil. Ik neem aan dat dat ook de overweging is van de topicstarter :)
Daar zit idd wel wat in (had ik zelf ook op het eerste moment aan ged8) maar wat doe je nu, als je bijv. een .php file wilt aanbieden, een direct url zal dan de file in de browser openen. Dan zou je hem wel kunnen zippen, maar je snapt denk ik wel mijn punt...

[ Voor 10% gewijzigd door bgever op 07-03-2003 15:29 . Reden: onnodig veel gequoted ]


Acties:
  • 0 Henk 'm!

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 17:06

gorgi_19

Kruimeltjes zijn weer op :9

oikoyama schreef op 07 March 2003 @ 15:28:
[...]

Daar zit idd wel wat in (had ik zelf ook op het eerste moment aan ged8) maar wat doe je nu, als je bijv. een .php file wilt aanbieden, een direct url zal dan de file in de browser openen. Dan zou je hem wel kunnen zippen, maar je snapt denk ik wel mijn punt...
nee hoor, juiste contenttype meesturen.. :)

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Acties:
  • 0 Henk 'm!

  • Sponge
  • Registratie: Januari 2002
  • Laatst online: 10-09 12:16

Sponge

Serious Game Developer

drm schreef op 07 maart 2003 @ 15:04:
Over het algemeen wil je bij files die je ter download aanbied via een script de bezoeker ergens toe verplichten. Als je simpelweg redirect naar een file, kan de url achterhaald worden, en kan iedereen leechen wat hij wil. Ik neem aan dat dat ook de overweging is van de topicstarter :)
Uiteraard. Ik zat ook al te denken dat daarom voor deze methode gekozen is (wordt)... maar ik wou het toch maar even melden, misschien had de TS er niet aan gedacht (als het niet per se zo "geheim" moet ;))

Acties:
  • 0 Henk 'm!

Verwijderd

Als je nu je huidige header :
header("Content-type:application/download");

Vervangt door deze :
code:
1
header("Content-type: application/octet-stream");


Dan zou het beter moeten gaan ik heb een dergelijk download systeem gemaakt.

Zou je deze regel niet weg halen ? Zo geef je namelijk het originele pad weer als het een keer mis gaat en dat is denk ik niet de bedoeling.

code:
1
echo $document_root . $file . "not found";

Acties:
  • 0 Henk 'm!

  • Postman
  • Registratie: Februari 2000
  • Laatst online: 12-09 01:23
Verwijderd schreef op 07 March 2003 @ 16:58:
Als je nu je huidige header :
header("Content-type:application/download");

Vervangt door deze :
code:
1
header("Content-type: application/octet-stream");


Dan zou het beter moeten gaan ik heb een dergelijk download systeem gemaakt.
Zo staat het ook in de PHP manual. Ik heb dit laatst nog gemaakt (een download script), en heb alleen maar de manual gebruikt.
Ik vind application/download ook maar een rare content-type. Je wil namelijk het programma dat geassocieerd is met download starten (en omdat dat er waarschijnlijk niet is, sla je dus een rare filenaam op).

Acties:
  • 0 Henk 'm!

Verwijderd

Een oplossing voor het probleem van Netscape en Opera is voornamelijk dat er een *.php extensie van wordt gemaakt. Dit kun je echter voorkomen met een slim maar lastig te vinden truukje: Zet een slash achter de URL van het downloaden.

Ofwel, stel de download link is: http://www.domein.nl/download.php?file=file.zip dan maak je daar van: http://www.domein.nl/download.php/?file=file.zip

Er is btw een topic over geweest waaruit ik een tijdje geleden dit truukje leerde kennen en dan met name deze post.

[ Voor 20% gewijzigd door Verwijderd op 07-03-2003 23:14 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hoi,
Bedankt voor alle reakties. De redirect wordt idd niet gebruikt omdat ik eerst wil checken of de audio-file er is, dan een record in een database wil zetten, en dan de file aanbiedt.
Door het content type download/octet-stream te maken, lijken de problemen opgelost. Mozilla, Netscape en Opera zijn dan in staat de filenaam over te nemen. Netscape zet er nog wel wat voor, maar maakt er niet meer de naam van het script van. Dus dat is al een hele verbetering.

Ik heb die error regel 'document not found' weggehaald. Bedankt voor de tip.
Markuz, jouw tip met die slash lijkt niet nodig te zijn, maar ik zel het onthouden. Ik zal het topic dat daarover gaat lezen. Lijkt me interessant om te weten.

Acties:
  • 0 Henk 'm!

  • slm
  • Registratie: Januari 2003
  • Laatst online: 12-11-2023

slm

Verwijderd schreef op 07 March 2003 @ 23:11:
Een oplossing voor het probleem van Netscape en Opera is voornamelijk dat er een *.php extensie van wordt gemaakt. Dit kun je echter voorkomen met een slim maar lastig te vinden truukje: Zet een slash achter de URL van het downloaden.

Ofwel, stel de download link is: http://www.domein.nl/download.php?file=file.zip dan maak je daar van: http://www.domein.nl/download.php/?file=file.zip

Er is btw een topic over geweest waaruit ik een tijdje geleden dit truukje leerde kennen en dan met name deze post.
Thx. Heel handig om te weten. Mozilla zet er anders inderdaad .php achter heb ik gemerkt.

Het is alleen niet verstandig om een script te maken die het volgende kan uitvoeren: http://www.domein.nl/download.php?file=file.zip

Als ik namelijk http://www.domein.nl/down...curitygevoeligbestand.ext doe kan men ook bestanden downloaden die niet daarvoor bedoeld zijn. PHP scripts kunnen op deze manier zomaar gedownload worden, dus als daar bv. een connect string in staat van een database, kan je database worden gehacked...

Beter is om een lijst te maken van downloadbare bestanden en de id-nr hiervan meegeven aan het script.

To study and not think is a waste. To think and not study is dangerous.


Acties:
  • 0 Henk 'm!

Verwijderd

slm schreef op 09 March 2003 @ 18:09:
...

Het is alleen niet verstandig om een script te maken die het volgende kan uitvoeren: http://www.domein.nl/download.php?file=file.zip

...
Het was ook slechts een voorbeeld :)

Ik kon zo snel ff niks anders verzinnen dan wat in het betreffende topic stond.

Maar je hebt gelijk, alhoewel je met een aantal checks ook gewoon veilig kunt werken met een dergelijke param.

[ Voor 14% gewijzigd door Verwijderd op 09-03-2003 19:21 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Vraagje slm; kan dit stukje code ook om problemen vragen? (qua security)

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$file_path    = $download_dir . "/" . $productname . "/" . $int_typpath . "/" . $_GET['file'];

  $filesize = filesize( $image_path );
  header("Expires: Mon, 11 May 19982 09:21:00 GMT" );
  header("Last-modified: " . gmdate("D, d M Y H:i:s") . " GMT" );
  header("Cache-Control: no-cache, must-revalidate");               // HTTP/1.1 header RFC
  header("Pragma: no-cache");                                               // HTTP/1.0 header RFC
  header( "Content-Disposition: filename=" . $filename );
  header( "Content-length: {$filesize}" );
  if ( $file_ext == "jpg" ) { $file_ext = "jpeg"; }
    
  header( "Content-type: image/{$file_ext}" );
  
  //@readfile($image_path); people say this cause problems with binary files....
  $fp = fopen( $image_path, "r" ); 
  fpassthru( $fp );


"application/octet-stream"; kun jij deze MIME-type ook gebruiken voor plaatjes?

[ Voor 64% gewijzigd door Verwijderd op 09-03-2003 20:11 ]


Acties:
  • 0 Henk 'm!

  • slm
  • Registratie: Januari 2003
  • Laatst online: 12-11-2023

slm

Verwijderd schreef op 09 maart 2003 @ 19:47:
Vraagje slm; kan dit stukje code ook om problemen vragen? (qua security)
...
"application/octet-stream"; kun jij deze MIME-type ook gebruiken voor plaatjes?
Dit script (zoals ik het hier zie) zorgt direct voor problemen.

Stel: je hebt dit script "test.php" genoemd en je script dat je database benadert heet .mysql.inc en staat in /db/ (dus bv met een mysql connect string)

Als ik vervolgens test.php?image_path=/db/.mysql.inc&file_ext=jpeg in mijn browser intik voorafgegaan door jouw domein naam kan ik zo je mysql wachtwoord lezen uit je script.

Let wel: die vars die je in het begin van het script hebt neergezet kunnen het e.e.a. nog bemoeilijken als je die ook daadwerkelijk gebruikt. Dat is nu niet te zien namelijk. Dan nog valt het te omzeilen door bv .. te gebruiken om een directory hoger te gaan zitten.

To study and not think is a waste. To think and not study is dangerous.


Acties:
  • 0 Henk 'm!

  • chris
  • Registratie: September 2001
  • Laatst online: 11-03-2022
reyer: verander
PHP:
1
$_GET['file'];


in:

PHP:
1
basename($_GET['file']);


en volgens mij is het dan zo veilig als het maar kan.

Acties:
  • 0 Henk 'm!

  • slm
  • Registratie: Januari 2003
  • Laatst online: 12-11-2023

slm

/dev/null schreef op 09 March 2003 @ 21:08:
reyer: verander
PHP:
1
$_GET['file'];


in:

PHP:
1
basename($_GET['file']);


en volgens mij is het dan zo veilig als het maar kan.
Tenzij er in de directory zelf ($download_dir . "/" . $productname . "/" . $int_typpath . "/") ook nog bestanden staan die niet gezien mogen worden zoals .htaccess files, php files e.d.

Maar het is idd al een stuk veiliger en als je er nog een check bijzet wat voor type bestand er wordt gerequest, dan kan je het wel online zetten.

Toch is het veiliger geen directe input te accepteren. Als je het niet in een database wil zetten (wat ik kan begrijpen omdat het een stuk arbeidsintensiever is), kan je er evt nog een txt bestand van maken die je wat makkelijker kan genereren.

To study and not think is a waste. To think and not study is dangerous.


Acties:
  • 0 Henk 'm!

Verwijderd

Hmm. Ik dacht dat je alleen $_GET['''] kon gebruiken bij register_globals = off.
Overigens gebruik ik geen db; en staan er alleen plaatjes in :)

Ben momenteel bezig met extensie check; zodat ie alleen jpeg, jpg, gif, png, doc pakt :)

Overigens, geef ik ook een productnaam mee; dat is de eigenlijke directory.

[ Voor 19% gewijzigd door Verwijderd op 09-03-2003 22:27 ]


Acties:
  • 0 Henk 'm!

Verwijderd

slm schreef op 09 March 2003 @ 20:58:
[...]
Als ik vervolgens test.php?image_path=/db/.mysql.inc&file_ext=jpeg in mijn browser intik voorafgegaan door jouw domein naam kan ik zo je mysql wachtwoord lezen uit je script.
Ja, leuk dan heb je het wachtwoord... Wat dan? :S
MySQL server is niet aangesloten op inet, maar op LAN :+
en de mysql gebruiker kan alleen verbinden vanaf localhost.

Acties:
  • 0 Henk 'm!

  • slm
  • Registratie: Januari 2003
  • Laatst online: 12-11-2023

slm

Verwijderd schreef op 09 March 2003 @ 22:29:
[...]


Ja, leuk dan heb je het wachtwoord... Wat dan? :S
MySQL server is niet aangesloten op inet, maar op LAN :+
en de mysql gebruiker kan alleen verbinden vanaf localhost.
1. Dat is niet bij iedereen het geval
2. Als je phpadmin op je site hebt staan en het is niet beveiligd met een ander wachtwoord of ipadres, kan men dus alsnog in je database klooien
3. Bij sommige providers is het mysql wachtwoord hetzelfde als de remote site administration login
4. het is ook al is al het bovenstaande niet van toepassing, gewoonweg niet netjes.

Je geeft net aan dat er alleen maar plaatjes in de dir staan. Als er alleen plaatjes in staan, waarom gebruik je dan een script als ik vragen mag?

To study and not think is a waste. To think and not study is dangerous.


Acties:
  • 0 Henk 'm!

Verwijderd

Omdat die plaatjes geld kosten :p

Acties:
  • 0 Henk 'm!

  • slm
  • Registratie: Januari 2003
  • Laatst online: 12-11-2023

slm

Verwijderd schreef op 09 March 2003 @ 23:50:
Omdat die plaatjes geld kosten :p
Hmmm... ik kan zo gauw de html code voor mijn Paypal donation button niet vinden.. :9

Maar als die plaatjes geld kosten, dan hoop ik voor je met je huidige script dat je dan direct alle plaatjes mag zien, anders heeft je scriptje nóg niet veel nut. Zeker niet als de plaatjes consequent benaamd zijn (viesplaatje01.jpg, viesplaatje02.jpg, viesplaatje03.jpg etc) want dan kunnen ze gewoon de file= wijzigen in het gewenste plaatje :)

To study and not think is a waste. To think and not study is dangerous.


Acties:
  • 0 Henk 'm!

  • Expander
  • Registratie: Februari 2001
  • Niet online
Ik heb het zo opgelost, een download wordt door een bepaalde url opgevraagd, met aan het eind de filename. Bijvoorbeeld:

http://blaat.com/fileophaler/schaap.zip

Je kan dan een script alles laten afhandelen, ook op deze manier kan je bijvoorbeeld zorgen dat url's niet te achterhalen zijn. (door bijvoorbeeld een id te posten)

Natuurlijk stuur ik tevens steeds de juiste headers.

[ Voor 6% gewijzigd door Expander op 10-03-2003 00:06 ]

Expanding the inexpandable


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

PHP:
1
2
3
//@readfile($image_path); people say this cause problems with binary files....
$fp = fopen( $image_path, "r" ); 
fpassthru( $fp );
reyer
Als readfile problemen veroorzaakt (bij inmiddels alleen de oudere versies, zie de manual), dan is dat op Windows systemen, en heb je met deze code op windows systemen alsnog een probleem met binaire bestanden

Maak er dan
code:
1
$fd = fopen ( "bestand", "r<b>b</b>" );
van.

offtopic:
Verder het vriendelijke verzoek om even de edit button te gebruiken, daar is hij voor. Als je wat toe te voegen hebt aan een post, reply dan niet, maar edit je post even. (tenzij er natuurlijk alweer anderen gereageerd hebben)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz

Pagina: 1