PHP - bezpieczeństwo w PHP - zagrożenie wynikające z włączonej opcji regisdter_globals
| DZIAŁANIE: | brak działania |
Kod:
brak kodu
Ewentualne Objaśnienia:
PHP w starszych wersjach posiadał domyślnie włączoną opcję register_globals - powodowało to umieszczenie wszelkich danych wejściowych (parametrów) z formularzy ( metoda POST i GET) oraz COOKIES w zmiennych globalnych, które były dostępne z każdego miejsca w programie. Kiedy opcja ta jest włączona - atakujący ma bardzo duże możliwości manipulacji działaniem skryptu PHP.
Przykładowo kod odpowiadający z wejście do panelu admina mógłby wyglądać tak :
if (sprawdz_admin() == 1)
{
$admin =1;
}
if ($admin)
{
wyswietl_panel_admina();
}
else
{
blad_logowania();
}
To bardzo prosty kod, który poprzez zewnętrzne funkcje sprawdza nasze
logowanie. Jeżeli użytkownik poda poprawne dane ( jakieś hasło itd ) ustawiana
jest zmienna globalna $admin - pozwala ona dalej wyświetlić panel administratora
serwisu.
Niby wszystko w porządku - ale zauważcie, że zmienna ta jest dopiero tworzona
kiedy odpowiednia funkcja ma wartość 1 (true) w przeciwnym razie w ogóle nie
jest ona tworzona, nie istnieje.
W przypadku kiedy na serwerze byłaby włączona opcja register_globals - możemy sami łatwo sobie tą zmienna stworzyć i nadać jej wartość TRUE. Jeżeli przykładowo skrypt nazywa się index.php - wpisujemy sobie po prostu index.php?admin=1 - spowoduje to utworzenie zmiennej $admin i nadanie jej wartości 1. W wyniku tego nawet jeżeli funkcja sprawdz_admin() zwróci wartość inną niż 1, zdobędziemy prawo admina ponieważ zmienna $admin będzie już sobie "czekać" z wartością 1 od samego początku działania kodu.
Jak więc się bronić ?
- zdecydowanie nie korzystać z register_globals
- zamiast osadzać parametry w postaci zmiennych globalnych należy korzystać z
tablic je przechowujących czyli $_GET[], $_POST[] oraz $_COOKIE[]
Jeśli jednak w przypadku naszego przykładu register_globals musi być włączone - należy utworzyć zmienną $admin niezależnie od wyniku działania funkcji sprawdz_admin() , czyli coś takiego :
if (sprawdz_admin() == 1)
{
$admin =1;
}
else
{
$admin =0;
}
if ($admin)
{
wyswietl_panel_admina();
}
else
{
blad_logowania();
}
Teraz widać, że już niezależnie od na przykład przekazanej zmiennej $admin poprzez metodę GET - kontrolujemy jej wartość, zależnie od funkcji sprawdz_admin() .
Od wersji 4.1 PHP opcja register_globals jest domyślnie wyłączona - ale należy to kontrolować - zawsze ktoś może przez nieuwagę czy niewiedzę ją włączyć.
Jeżeli jednak zależy nam zaimportowaniu niektórych parametrów do skryptu w postaci zmiennych globalnych, a register_globals jest wyłączone - zamiast ją włączać należy posłużyć się funkcją : import_request_variables() - zobacz jak to działa :
import_request_variables() - Importuje ona zmienne $_GET lub $_POST
lub $_COOKIES do skryptu.
Pierwszy argument określam które zmienne chcemy importować:
‘p’ – POST
‘g’ – GET
‘c’ – COOKIES
Frugi argument (nieobowiązkowy) można podać, prefix jaki będzie stosowany dla
importowanych zmiennych. Przydaje się to na przykład wtedy gdy w kodzie mamy
zmienną o takiej samej nazwie, jaką będziemy importować z formularza.
Prosty przykład :
- formularz:
<form action="skrypt.php" method="post">
<input type="text" name="dane">
<input type="submit" value="wyślij">
</form>
- skrypt:
<?php
import_request_variables("p", "formularz");
print $formularz_text;
?>
Proste prawda :) Jedziemy dalej !