Guide:
Sikker bruk av include-script
Bruken av dynamiske include-script har tatt seg opp voldsomt i det siste, siden flere og flere får snusen på hva noen korte PHP-snutter kan gjøre for å forenkle driften av deres hjemmeside. Det mange ikke tar med i beregningen er hvor lett et slikt script kan lures til å hente ondsinnete filer, eller i verste fall ta over hele systemet. Det skal vi prøve å ta et lite oppgjør med her.
Løsninger
Siden et dynamisk include-script tar imot variabler direkte fra bruker, må man være veldig forsiktig med hva man tar imot, og dermed må man validere hva bruker sender. Det kan gjøres med bl.a. regulære uttrykk (regular expressions), å kun akseptere filnavn som begynner på en viss bokstav/rekke bokstaver eller ved å sjekke om det som inkluderes ligger i en forhåndsdefinert liste over godkjente filer. Sistnevnte er ikke så veldig aktuell for de som vil ha en selvgående løsning, da dette innebærer at man må oppdatere listen for hver nye side som legges til.
Eksempel 1 – Regular Expressions
<?php
error_reporting(0);
$filnavn = $_GET['s'];
$filendelse = '.php';
if (!$filnavn) {
$filnavn = 'forside';
}
if (!eregi("^((.*)/)", $filnavn)) {
include $filnavn . $filendelse;
}
else {
include "404.php";
}
?>
Denne benytter seg et regulært uttrykk for å teste om filnavnet ikke inneholder tegnet "/". Dermed er det umulig å bruke scriptet til å få tak i filer utenfor den mappen. Hvis ikke filen finnes, inkluderes filen 404.php, som kan inneholde en beskjed om at brukeren er kommet feil.
Eksempel 2 – Bokstavleken (:p)
<?php
error_reporting(0);
$filnavn = $_GET['s'];
$filendelse = '.php';
include 'abc' . $filnavn . $filendelse;
?>
Dette scriptet inkluderer bare filer med filnavn som begynner på "abc", og dermed er det umulig for andre å inkludere filer fra andre steder. Hvis du i tillegg spesifiserer en mappe filene skal hentes fra, er det nesten skuddsikkert. Legg merke til bruken av funksjonen error_reporting(). Når den er satt til 0, blir feilrapporteringen i PHP skrudd av, og include-funksjonen vil derfor ikke returnere en feilmelding hvis filen ikke finnes. Det gjør det ekstra vanskelig for inntrengere, samt at brukerne ikke får opp stygge feilmeldinger fra PHP hvis det skjer noe galt.
Eksempel 3 – Kun tillatte filer
<?php
error_reporting(0);
$filnavn = $_GET['s'];
$tillatt = array("index", "articles", "links");
$filendelse = '.php';
if (in_array($filnavn, $tillatt)) {
include $filnavn . $filendelse;
}
else {
include '404.php';
}
?>
Denne varianten av scriptet inneholder først et array som inneholder alle de tillatte filnavnene. Deretter sjekkes det med funksjonen in_array() om den filen som skal inkluderes er med i arrayet. Hvis den er det, inkluderes filen. Hvis ikke, inkluderes en 404-fil som kan inneholde en beskjed om at brukeren er kommet feil. PS: in_array() er følsom for forskjeller mellom stor og liten bokstav.
Konklusjon
Mange begynner å få øynene opp for hva PHP kan gjøre for å forenkle deres hverdag som webmaster, og det er lett å finne små guider om dette på diverse nettsteder og fora. Dessverre er det ofte slik at disse guidene har noe særlig fokus på sikkerheten som trengs.
De tre overnevnte scriptene demonstrerer bare noen de alternativene man har når man skal lage et sikkert include-script. Det finnes sikkert flere hundre forskjellige variasjoner, alt fra enkle script på et par linjer til svære kolosser på over 50 linjer. Alt etter behov, altså. Av de tre overnevnte er det eksempel 1 som er mest aktuelt for de aller fleste, siden den ikke krever forandringer i filnavn eller struktur.
Hvis du aldri har vært borti PHP før er dette en god begynnelse. Jeg vil på det sterkeste anbefale alle som leser dette å kjøpe seg en god bok om PHP og komme i gang umiddelbart. Til dere andre som allerede kan PHP vil jeg anbefale å sette større fokus på sikkerheten i programmene dere skriver. Det er aldri gøy å oppdage at andre har ødelagt noe du har brukt veldig lang tid på å lage.