[PHP] alleen files openen binnen gegeven directory

Pagina: 1
Acties:

Onderwerpen


  • Bart B
  • Registratie: Juli 2000
  • Laatst online: 05-01 16:29
Hallo allemaal,

Ik ben nu al enige tijd bezig geweest om een verzameling scriptjes te schrijven, waarmee ik er voor kan zorgen dat alleen mensen met toegang bepaalde zaken kunnen bekijken. Onder de te beveiligen items vallen ook plaatjes.

Dit laatste is niets moeilijks aan. De plaatjes zelf zet ik 1 directory hoger, met een .htaccess file zodat niets of niemand toegang heeft. daarna een PHP script waarbij er met een variabele in de URL kan worden aangegeven welke file gedownload wordt.

de code:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?
// ACCESS CONTROL
require "CAccessControl.php";
$myCAccessControl_AuthAccessOnly = new CAccessControl();
if(!( $myCAccessControl_AuthAccessOnly->Status_LoggedIn() )) die();

$fetchfile_dir = "./no_access/";
$fetchfile_file = $_GET["file"];
$fetchfile_fullpath = $fetchfile_dir . $fetchfile_file;


// CHECK IF FILE EXISTS
if(!file_exists($fetchfile_fullpath)) die();

// CHECK IF FILE IS A PICTURE
if(!( $imageinfo = getimagesize ($fetchfile_fullpath)) ) die();

// SEND HEADER
header("Content-type: " . $imageinfo['mime'] . "");

// SEND FILE
readfile($fetchfile_fullpath);
?>


Dit zeer simpele maar doelmatige scriptje werkt hier goed. Echter 1 probleem.

Onderstaande link zou het gewoon doen, en daar is niks mis mee
https://mijnserver/bepaaldedir/fetchpicture.php?file=gewensteplaatje.jpg

Echter, de onderstaande doet het ook!!!!
https://mijnserver/bepaaldedir/fetchpicture.php?file=../../../../../eendir/anderplaatje.png

Het is dus mogelijk om terug te gaan in de directory structuur!!!

Nu zit ik dus te bedenken hoe ik er voor kan zorgen dat, ALLEEN files in de aangegeven directory, of in een directory binnen die directory kunnen worden opgehaald.

VRAAG: hoe kan ik checken of een pad binnen een bepaalde directory valt

[ Voor 13% gewijzigd door Bart B op 25-09-2003 22:19 ]


  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Lijkt me in dit geval simpel: als er een / in de filenaam voorkomt, dan is het fout. Als je wel wilt dat mensen in subdirs van de allowde dir mogen, dan is het fout als er ../ in voorkomt.

  • dusty
  • Registratie: Mei 2000
  • Laatst online: 15-09 18:24

dusty

Celebrate Life!

Misschien gewoon zorgen dat er geen / gebruikt mag worden?

Back In Black!
"Je moet haar alleen aan de ketting leggen" - MueR


  • Bart B
  • Registratie: Juli 2000
  • Laatst online: 05-01 16:29
Heb je echter nog een probleem, namelijk de ~userdir -directory's.

Is er niet een mogelijkheid om als het waren een check uit te voeren op het uiteindelijke pad, en dan te kijken of het binnen een ander pad valt?
Het is idd het makkelijks om te zeggen, wanneer er een / inzit mag je het niet ophalen. Ik wil echter binnen die plaatjesdir ook weer andere directory's maken om het voor mij ook overzichtelijk te maken en houden.

[edit]
gedeelte van de oplossing gevonden... maar nu... wil ik ook een subdir betreden
http://nl2.php.net/manual/en/function.basename.php
http://nl2.php.net/manual/en/function.realpath.php

[ Voor 56% gewijzigd door Bart B op 25-09-2003 22:29 ]


  • dusty
  • Registratie: Mei 2000
  • Laatst online: 15-09 18:24

dusty

Celebrate Life!

Dan zorg je dat er geen filenames met een dubbele punt in zitten en er geen speciale tekens in mogen zitten. ie ~ en dus niet de dubbele punt.

Back In Black!
"Je moet haar alleen aan de ketting leggen" - MueR


  • Suepahfly
  • Registratie: Juni 2001
  • Laatst online: 17-09 17:05
PHP:
1
2
3
4
if(!eregi(basename(dirname(__FILE__)), $_SERVER['PHP_SELF']))
{
     die("Acces denied");
}

Zou moeten werken.

[ Voor 33% gewijzigd door Suepahfly op 25-09-2003 22:34 ]


  • Bart B
  • Registratie: Juli 2000
  • Laatst online: 05-01 16:29
HET WERKT
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?
//ACCESS CONTROL... ONLY USERS WHO ARE LOGGED IN
require "CAccessControl.php";
$myCAccessControl_AuthAccessOnly = new CAccessControl();
if(!( $myCAccessControl_AuthAccessOnly->Status_LoggedIn() )) die();


$fetchfile_dir = "./no_access/";
$fetchfile_file = $_GET["file"];
$fetchfile_fullpath = $fetchfile_dir . $fetchfile_file;

//CONVERT PATHNAMES FROM RELATIVE TO ABSOLUTE
$realpath_fetchfile_fullpath = realpath($fetchfile_fullpath);
$realpath_fetchfile_dir = realpath($fetchfile_dir);

//CHECK IF FILE IS LOCATED WITHIN THE GIVEN DIRECTORY, OR ANY DIRECTORY BELOW
if(!ereg("^".$realpath_fetchfile_dir."/",$realpath_fetchfile_fullpath)) die();

// CHECK IF FILE EXISTS
if(!file_exists($fetchfile_fullpath)) die();

// CHECK IF FILE IS A PICTURE
if(!( $imageinfo = getimagesize ($fetchfile_fullpath)) ) die();

// SEND HEADER
header("Content-type: " . $imageinfo['mime'] . "");

// SEND FILE
readfile($fetchfile_fullpath);
?>


Wat heb ik gedaan
1) Ik laat de paden omzetten van relatief naar absoluut.
2) Ik doe een ereg replace

Bij de EREG REPLACE moet je er op letten dat er een "^" voor geplakt wordt. Volgens de handleiding checked hij dan of het patroon meteen in het begin start. Anders zou het patroon ook middenin de string kunnen beginnen (dit is redelijk onwaarschijnlijk, maartoch).
Verder moet je achter de searchstring een "/" plakken. anders zou het ook geldig zijn om een pad te hebben waarbij een andere directory wordt geaccessed, die een paar tekens meer heeft (zoals "dir", "dir2" enzovoort).

[ Voor 27% gewijzigd door Bart B op 25-09-2003 22:56 ]

Pagina: 1