Kan iemand me vertellen wat ik nog meer kan beveiligen met dit script?

<?php if(!empty($_GET['p'])){
      $pages_dir = "pages";
      $pages = scandir($pages_dir, 0); 
unset($pages[0], $pages[1]);
$p = $_GET['p'];

    if(in_array($p. '.php', $pages)) {
        include($pages_dir .'/'. $p .'.php');
    }else{
        echo 'Sorry pagina niet gevonden';
    }

}else{
    include ('pages/home.php');
}; ?> 

Het is de bedoelding als je $_GET['p'] hebt dat ie dan de pagina include.

Alvast bedankt!
Stel jij hebt een pagina die iemand niet mag zien, bijvoorbeeld "geheim.php". Op jouw manier kan iedereen die pagina aanroepen.

Jouw manier kan sowieso korter:

<?php
$page = $GET['p'];
if (!empty($page)) {
if (is_file('pages/'.$page.'.php')) {
include 'pages/'.$page.'.php';
}
} else {
include ('pages/home.php');
}
?>

Veiliger is het om gebruik te maken van de switch constructie www.php.net/switch of om de paginaverwijzingen op te slaan in een database. Voorbeeldje van switch:

<?php
switch ($page) {
case 'mijnpagina':
$include = 'mijnpagina.php';
break;
default:
$include = 'home.php';
}
include $include;
?>
Hoezo is die switch veiliger? want dan kan ik via de adres balk toch overal komen?
Nee hoor, juist niet.

Alleen pagina's die in de switch zijn opgenomen als 'case' kunnen worden aangeroepen.
Ozzie PHP

Veiliger is het om gebruik te maken van de switch constructie

Bob van der Valk

Hoezo is die switch veiliger? want dan kan ik via de adres balk toch overal komen?


Terechte opmerking. Het is niet veiliger. Het is enkel een andere manier van werken, waardoor het makkelijker is veiliger te werken. Echter zou ik in dit geval toch opteren voor een if-else structuur. Die structuur is krachtiger en daardoor kan je het iets flexibeler maken. Je hoeft nl. niet elke case te definiëren, bespaart je tijd. Een case-switch zal echter wel iets sneller doorlopen worden dan een if-else. Echter moet hier maar 1 statement gecontroleerd worden, dus maakt het sowieso amper uit. Eveneens is het zo dat je veel meer cases nodig hebt om hetgeen te bereiken wat ik in onderstaand script heb geplaatst. Dus, je komt sneller uit met een if-else ;-)


<?php
$sPage = $_GET['p'];
$aDissalowed = array('admin.php', 'payments.php', 'secret.php');
/* 
* In dit geval is file_exists meer toepasselijk dan is_file
* In je voorbeeld waarin je een directory uitleest, zou is_file een betere keuze zijn
*/
if(file_exists('/path'.$sPage) && !in_array($sPage, $aDissalowed)) {
	/* 
	* Het bestand bestaat -> OK 
	* Het bestand mag bekeken worden -> OK
	*/
	include_once('/path/'.$sPage);
}else {
	/* 
	*	Je komt in else structuur omdat:
	* - Bestand niet bestaat
	* - Bestand bekijken niet toegestaan is 
	*/
	include_once('/path/home.php');
}

/* Dit is veilig + flexibeler dan Ozzie's methode */ 
?>


@Write down?

Wat denk je van ?p=../path/admin.php

Dan kan ik alsnog het bestand admin.php includen. (En verder alle andere bestanden waar de gebruiker bij kan waar de website onder draait)
Oftewel het is NIET veilig.
Foutje, inderdaad. Maar is makkelijk op te lossen / te voorkomen :-)
Foutje? manier om je hele server op en bloot te geven aan een hacker.
TJVB tvb op 21/04/2011 13:11:50

Foutje? manier om je hele server op en bloot te geven aan een hacker.


Heb je gelijk in. grote foutje Maar alsnog eenvoudig te vermijden.
Dus btw: ik schiet hier niet veel mee op. Want ook in de pages map ga ik geen bestanden plaatsen die andere niet mogen zien. Dus ik denk dat ik em gewoon zo hou.

Maar bedankt in ieder geval dat er naar gekeken is. Top
Bob, jouw manier zorgt er dus voor dat je iedere willekeure PHP bestand kan includen. Hierin kun je dus geen white/black list maken. Niet veilig dus.

Reageren