[PHP] Secure file download uit variabele map

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

Onderwerpen


Acties:
  • 0 Henk 'm!

  • denyos
  • Registratie: Februari 2004
  • Laatst online: 17:15
Goedenavond,

Na al heel wat uurtjes af gestoeid te hebben, roep ik toch maar wat hulp in. Mijn probleem is het volgende:
Ik heb een map met bestanden die ik heb afgeschermd met een .htaccess file, dit om dieplinken te voorkomen. Dus heb ik ook een stukje code geschreven dat de bestanden moet kunnen downloaden.
Op zich werkt het wel, maar als ik bestanden uit een map wil halen dan gaat het fout. Hieronder eerst even mijn code
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
if (isset($_REQUEST["file"])) 
{
    $filename = $_REQUEST["file"];
    header('Content-type: application/octet-stream');
    header('content-length: '.filesize("files/".$filename.''));
    header('content-disposition: attachment; filename=files/'.$filename.'');
    $fp=fopen('files/'.$file, 'r');
    fpassthru($fp);
} 
else
{
    echo "No file selected";
}
?>

Misschien dat dit niet de meest slimme methode is, maar dit is dan te wijten aan gebrek aan ervaring. Zoals in de code te zien is wel ik bestanden halen uit de map files. Alleen krijg ik nu een bestand zonder inhoud (grootte 2 bytes).

Ik heb ook geprobeerd om een veriabele $dir aan te maken met daarin de waarde files/. Dit om vervolgens
code:
1
$filename = $dir.$_REQUEST["file"];
te doen. Het resultaat hiervan was dat mijn bestand naar mij toegestuurd werd met als bestandsnaam files-blaat.htm (ervan uit gaan dat het bestand wat ik opvroeg blaat.htm was).

[ Voor 0% gewijzigd door denyos op 30-01-2007 20:11 . Reden: php tags ]

Strava


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

PHP:
7
    header('content-disposition: attachment; filename=files/'.$filename.'');

doe die 'files/' eens weg.

Dan krijg je dit:
PHP:
7
    header('content-disposition: attachment; filename='.$filename.'');


Edit: Overigens is dit niet veilig, ik kan daarmee evengoed de htaccess uitlezen door file.php?file=.htaccess doen. Of een dir hoger gaan: file.php?file=../../../index.php oid.

Bouw daar een aantal tests op in.

[ Voor 36% gewijzigd door Snake op 30-01-2007 20:10 ]

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • denyos
  • Registratie: Februari 2004
  • Laatst online: 17:15
van die veiligheid was ik inderdaad op de hoogte. Daar moeten zeker nog een lading tests voor in. Na het weghalen van die files/ heb ik helaas nog steeds hetzelfde probleem.

Strava


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

http://be.php.net/fpassthru

Kijk hier eens.

En kijk eens naar die binairy mode :)

Succes ;)

Overigens moet je header wel juist zijn. Verander die dus niet in Image/png

[ Voor 28% gewijzigd door Snake op 30-01-2007 20:33 ]

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • denyos
  • Registratie: Februari 2004
  • Laatst online: 17:15
Bedankt voor de tip, ik zit alleen nog steeds met het probleem dat mijn slash wordt omgezet in een dash.
Dit is wat ik nu heb:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
if (isset($_REQUEST["file"])) 
{
    $filename = "files/".$_REQUEST["file"];
    header('Content-type: application/octet-stream');
    header('content-length: '.filesize($filename.''));
    header('content-disposition: attachment; filename='.$filename.'');
    $fp=fopen($filename, 'rb');
    fpassthru($fp);
} 
else
{
    echo "No file selected";
}
?>

Strava


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
if (isset($_GET["file"])) 
{
    $filename = "files/".$_GET["file"];
    header('Content-type: application/octet-stream');
    header('content-length: '.filesize($filename.''));
    header('content-disposition: attachment; filename='.$filename.'');
    $fp=fopen($filename, 'rb');
    fpassthru($fp);
} 
else
{
    echo "No file selected";
}
?>

=> Mind the GET, ipv de REQUEST :)

Plaats dat nu eens in een map, maak een submap aan met de naam 'files', en smijt daar een bestand in.
En link dan naar file.php?file=naamvandefile.exe

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • Pyrus
  • Registratie: November 2001
  • Laatst online: 20-09 21:30

Pyrus

Hardknock life

denyos schreef op dinsdag 30 januari 2007 @ 20:40:
Bedankt voor de tip, ik zit alleen nog steeds met het probleem dat mijn slash wordt omgezet in een dash.
Dit is wat ik nu heb:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
if (isset($_REQUEST["file"])) 
{
    $filename = "files/".$_REQUEST["file"];
    header('Content-type: application/octet-stream');
    header('content-length: '.filesize($filename.''));
    header('content-disposition: attachment; filename='.$filename.'');
    $fp=fopen($filename, 'rb');
    fpassthru($fp);
} 
else
{
    echo "No file selected";
}
?>
een slash mag niet in een bestandsnaam, zoals je nu probeert te doen. Maak er iets als dit van:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
if (isset($_REQUEST["file"])) 
{
    $filename = $_REQUEST["file"];
        $filepath="files/".$filename;
    header('Content-type: application/octet-stream');
    header('content-length: '.filesize($filepath));
    header('content-disposition: attachment; filename='.$filename);
    $fp=fopen($filepath, 'rb');
    fpassthru($fp);
} 
else
{
    echo "No file selected";
}
?>

Ook nog wat onnodige aanhalingstekens weggehaald trouwens....

Oh en op veiligheid letten natuurlijk ook hierbij :P

LinkedIn


Acties:
  • 0 Henk 'm!

  • denyos
  • Registratie: Februari 2004
  • Laatst online: 17:15
helaas werkt het nog steeds niet. De bestandsnaam komt nu inderdaad goed binnen, alleen blijven de bestanden 2 bytes groot. Dit heb ik geprobeerd met zowel de GET als de REQUEST manier in de code van Pyrus. Tevens heb ik dit op 2 losse hosting servers geprobeerd.

Strava


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

@*&#$*# verkeerd.

Ipv fpasstru gebruik eens readfile();

http://php.net/readfile

[ Voor 75% gewijzigd door Snake op 30-01-2007 22:05 ]

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • denyos
  • Registratie: Februari 2004
  • Laatst online: 17:15
okay... wie heeft er zin om me een geweldige rot trap te verkopen? ik had een lijst met bestanden uit een folder laten genereren in php en hier een linkje van gemaakt naar de download. Alleen bleek ik aan te hebben staan dat ook mijn subdirectories werden doorzocht 8)7 en ja die bestanden deden het nog niet. |:( Oftewel, hij deed het al een sinds de aanpassingen van pyrus.

Voor mensen die dit topic gevolgd hebben / ooit nog gaan vinden met de search. Dit is wat het uiteindelijk is geworden
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
if (isset($_GET["file"])) 
{
    $filename = $_GET["file"];
    $filepath="files/".$filename;
    header('Content-type: application/octet-stream');
    header('content-length: '.filesize($filepath));
    header('content-disposition: attachment; filename='.$filename);
    header('Content-Transfer-Encoding: binary');
    //readfile($filepath);
    $fp=fopen($filepath, 'rb');
    fpassthru($fp);
} 
else
{
    echo "No file selected";
}
?>


Je kan zelf kiezen of je readfile wilt gebruiken of fpassthru, het werkt allebei.

Strava

Pagina: 1