PHP: register_globals

Autor: Arkadiusz Tobiasz 2 listopada 2008

Czytając magazyn „Hakin9” natknąłem się na ciekawy artykuł dotyczący bezpieczeństwa w PHP – „BHP w PHP”. Artykuł ukazuje najbardziej słabe punkty tej jednej z najpopularniejszych technologii wykorzystywanej do tworzenia dynamicznych stron interetowych. Ten wpis jest dla osób zaczynających dopiero „zabawę” z PHP, a także tych, którzy chcieliby się jeszcze czegoś dowiedzieć o słabych punktach tej technologii.

Najsłynniejszym problemem w PHP jest dyrektywa register_globals, która została usunięta od wersji 6.0.0, a od wersji 4.2.0 jest domyślnie wyłączona (administrator serwera mógł ją włączyć). Co było nie tak z tą dyrektywą?

Chodzi o to, że zmienne z tablic asocjacyjnych takich jak $_GET, $_SESSION czy $_POST były automatycznie konwertowane na zwykłe zmienne, czyli zmienna $_GET[‚zmienna’] była tożsama z zapisem $zmienna. Bowiem dyrektywa register_globals kiedy używamy jakiejś zmiennej, np. $inna_zmienna przeszuka wszystkie tablice asocjacyjne i  zatrzyma się na pierwszej, która będzie posiadała taką samą nazwę. W związku z tym jakie zagrożenie to niesie ze sobą?

Spróbuję to wyjaśnić na przykładzie prostego skryptu administracji. Wygląda on tak:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

session_start();

if(!isset_(is_admin)) {          // sprawdzanie czy istnieje zmienna, jesli nie to wykonuje sie warunek
    if($login == "admin" && $pass == "haslo") {          // sprawdzanie czy uzytkownik podal wlasciwe dane w formularzu logowanie
          $_SESSION['is_admin'] = true;
    } else {
          $_SESSION['is_admin'] = false;
    }
}

if($is_admin) {
     echo "Witaj w Panelu Administratora";
} else {
     echo "Brak dostępu";
}
?>

Jak działa skrypt, na początku skrypt sprawdza czy istnieje sesja o nazwie is_admin. Jeżeli taka sesja nie istnieje, to wtedy sprawdza login i hasło podane w oknie logowania. Kiedy dane są poprawne ustanawiana jest sesja, w przeciwnym wypadku nie. Następnie skrypt sprawdza czy istnieje zmienna is_admin, a przy włączonej dyrektywie register_globals zostają przeszukane wszystkie tablice asocjacyjne, w tym $_SESSION[‚is_admin’].

Niby wszystko jest w porządku, ale co by się stało, gdybyśmy wpisali w pasku adresu naszej przeglądarki adres skrypt.php?id_admin=1? Strona pobierze wartość zmiennej $is_admin tym razem z tablicy asocjacyjnej $_GET[‚is_admin’], co spowoduje, że niepowołana osoba będzie miała dostęp do naszego panelu administracyjnego.

W związku z tym jak poprawić nasz skrypt, aby działał poprawnie? Wystarczy zmienić instrukcję !isset(is_admin) na !isset($_SESSION[is_admin’]).

Sam kiedyś, kiedy rozpoczynałem przygodę z PHP nie zwracałem uwagi na takie rzeczy, bo wszystko działało jak należy. Dopiero kiedy administrator wyłączył na serwerze dyrektywę register_globals i moja strona przestała działać zainteresowałem się problemem. W naszych skryptach, które piszemy najważniejszy powinien być bezpieczny kod, a nie to czy skrypt działa, czy nie, a zazwyczaj jest na odwrót.

Wracając do artykułu, to można w nim przeczytać jeszcze o zabezpieczeniu przed wysyłanie zbyt dużych plików i nie chodzi tutaj o dodanie ukrytego pola:

1
<input type="hidden" name="MAX_FILE_SIZE" value=1024" />

Bowiem to również nie jest bezpieczne. Oprócz tego znajdziemy garść informacji na temat SQL incjections, czyli jak pisać zapytania MySQL, aby zniwelować możliwość uzyskania niepowołanego dostępu do danych z naszej bazy, a także o tym jak bezpiecznie wykorzystywać polecenia systemowe w swoich skryptach, aby nie dać okazji użytkownikom do namieszania na naszym serwerze.

Ogólnie artykuł napisany bardzo fajnie, który daje do myślenia, szczególnie początkującym programistom PHP, nie zwracającym uwagi na kwestie bezpieczeństwa skryptów.

Odpowiedz

 

Arkadiusz Tobiasz student Akademii Ekonomicznej im. Karola Adamieckiego w Katowicach na specjalnościach informatyka ekonomiczna oraz rachunkowość. Więcej...

jQuery Validation i funkcja remote

Jakiś czas temu zwrócił się do mnie użytkownik z problemem. Chodzi o to, że korzysta on z pluginu walidacji jQuery, […]

Zend Framework: integracja z Uploadify

W tym wpisie postaram się przedstawić Wam w jaki sposób zintegrować skrypt Uploadify z Zend Frameworkiem. Dzięki temu będziemy mogli […]

Javascript: Czasowe wyświetlanie reklamy

Czasami chcemy, aby na pewnym elemencie naszej strony wyświetlała się reklama przez jakiś czas, a następnie zniknęła. W tym wpisie […]

Linux: backup wszystkich baz danych MySQL

Swego czasu pisałem o tym jak z poziomu konsoli można szybko i przyjemnie zrobić backup bazy MySQL. Wszystko jest ładnie […]