register_globals=off ... szkoła poprawnego pisania skrypt
: 17 paź 2005, 22:27:10
Witam,
w tym artykule/faq porusze kwestie pisania skryptów php zgodnie z zasadami zalecanymi przez autorów owego języka w wersjach od 4.2.0. Otóż ze względów bezpieczeństwa twórcy php zalecają wyłączenie dyrektywy register_globals w pliku php.ini (plik konfiguracyjny php) tak jak postąpił administrator tego serwisu. I teraz odrazu nasunie się nam na myśl dlaczego ten administrator tak nam uprzykrza życie .. ?? Otóż postaram się to wyjaśnić na przykładzie :
Widzimy standardowy skrypt autoryzacji użytkownika na stronie x . Oczywiście odbywa się on po wypełnieniu stosownego formularza. No i co z tego ?? Otóż php standardowo dla "wygody" programisty ma mechanizm zamiany wszystkich zmiennych[sesji,cook -ies,pochodzących z formularza] na zmienne globalne(czyli dostępne w całym skrypcie). Pomyślmy sobie co się stanie jeżeli ktoś sfałszuje adres naszej strony i wpisze www.xx.pl?$autoryzacja=1 ... Oczywiście odpowiedź jest prosta, zobaczy on "tajną" treść strony na pewno nie przeznaczoną dla niego. Jak zrobić żeby potencjalny agresor już tak nie zrobił ... ?? Dochodzimy więc do sedna sprawy, czyli sławnego register_globals = off; czyli mówiąc troche bardziej zrozumiałym językiem "wyłączenie" zmiennych globalnych. Jak wtedy "dostać" się do takiej zmiennej .. ?? W takim wypadku dostęp do zmiennych sesji etc .. jest możliwy za pośrednictwem tablic super globalnych takich jak :
$_GET[''] --> Dla zmiennych przesyłanych metodą GET
$_POST[''] --> Dla zmiennych przesyłanych metodą POST
$_SERVER[''] --> Dla zmiennych udostępnionych przez serwer www
$_SESSION[''] --> Dla zmiennych "sesyjnych"
$_COOKIE[''] --> Dla zmiennych cookies
$_FILES[''] --> Dla zmiennych opisująch upload -owany plik
$_ENV[''] --> Dla zmiennych środowiskowych
Czyli po zmianie nasz skrypt powinien wyglądać tak :
Na koniec postaram się wyjaśnić co to są te tablice superglobalne ...
Przy wyłączonej dyrektywie register_globals wszystkie zewnętrzne dane przychodzące do naszego skryptu są sortowane i przydzielane do odpowiednich tablic asocjacyjnych, czyli naszych tablic superglobalnych. Dlaczego nazywają sie superglobalne ?? Oczywiście sprawa jak zwykle idzie o zasięg zmiennych. Otóż są one dostępne w całym skrypcie.
Dlaczego więc autorzy tak dbajać o nasze bezpieczeństwo naszych skryptów dodali dyrektywe register_globals ??
Otóż dodali oni po to aby zachować zgodność ze starszymi skryptami i dać autorom tych skryptów czas do przemyśleń to (to ja już sobie sam dopowiedziałem). Dyrektywa ta jest domyślnie wyłączona(nieaktywna) czyli register_globals = off;
EDIT:
Zapomniałbym o przykładach w końcu z przykładów człowiek najlepiej się uczy. Wyobraźmy sobie, że wielka firma zleca p. Kowalskiemu napisanie "skryptu strony" opartego o funkcje include() , czyli np. po nadaniu odpowiedniej wartości zmiennej przekazywanej metodą GET powinna nam się ujrzeć odpowiednio includ -owana treść lub wykonany kod. Odrazu więc pan Kowalski zabierze się do pracy pisząc coś takiego :
Zadowolony "informatyk" włącza swój interpreter php wbudowany do swojego nowo zainstalowanego apach -a i ku wielkiemu zdziwieniu przy naciśnięciu na każdy odnośnik wraca do strony głównej. Przez następne pół dnia zachodzi w głowe co jest nie tak przecież wszystkie skrypty "śmigają" normalnie na serwerze firmy. Po długich trudach i "przekopaniu" x for dochodzi do zagadnienia jakim jest dyretkywa register_globals w php.ini.
Odrazu więc niczym szalony poprawia skrypt na zgodny z zaleceniami autorów php, czyli :
EDIT 2 :
Postanowiłem dodać jeszcze troche przykładów.
Przykład nr. 2 :
¬LE - powyższy przykład jest źle napisany
DOBRZE - powyższy przykład jest dobrze napisany
Przykład nr.3
¬LE - powyższy przykład jest źle napisany
DOBRZE - powyższy przykład jest dobrze napisany
Dla dociekliwych :
http://wiki.php.pl/index.php/Czemu_nie_ ... gradzie%3F
http://pl2.php.net/manual/pl/language.v ... .scope.php
http://pl2.php.net/manual/pl/language.v ... efined.php
http://php.faq.pl/klucz/global
http://forum.webhelp.pl/faqforum.php?f=1#34
Poprawki : Gacek , rzymek01
W razie pytań prosze nie pisać nowych postów pod tym FAQ lecz porozumieć się ze mną za pomocą PW, ponieważ robi się to nie czytelne a chyba nie o to chodzi.
w tym artykule/faq porusze kwestie pisania skryptów php zgodnie z zasadami zalecanymi przez autorów owego języka w wersjach od 4.2.0. Otóż ze względów bezpieczeństwa twórcy php zalecają wyłączenie dyrektywy register_globals w pliku php.ini (plik konfiguracyjny php) tak jak postąpił administrator tego serwisu. I teraz odrazu nasunie się nam na myśl dlaczego ten administrator tak nam uprzykrza życie .. ?? Otóż postaram się to wyjaśnić na przykładzie :
Kod: Zaznacz cały
if( $haslo == 'haslo' )
{
$autoryzacja = 1;
}
if( $autoryzacja == 1 )
{
echo 'Tajna tresc';
}
$_GET[''] --> Dla zmiennych przesyłanych metodą GET
$_POST[''] --> Dla zmiennych przesyłanych metodą POST
$_SERVER[''] --> Dla zmiennych udostępnionych przez serwer www
$_SESSION[''] --> Dla zmiennych "sesyjnych"
$_COOKIE[''] --> Dla zmiennych cookies
$_FILES[''] --> Dla zmiennych opisująch upload -owany plik
$_ENV[''] --> Dla zmiennych środowiskowych
Czyli po zmianie nasz skrypt powinien wyglądać tak :
Kod: Zaznacz cały
$haslo = $_POST['haslo']
if( $haslo == 'haslo' )
{
$autoryzacja = 1;
}
if( $autoryzacja == 1 )
{
echo 'Tajna tresc';
}
Przy wyłączonej dyrektywie register_globals wszystkie zewnętrzne dane przychodzące do naszego skryptu są sortowane i przydzielane do odpowiednich tablic asocjacyjnych, czyli naszych tablic superglobalnych. Dlaczego nazywają sie superglobalne ?? Oczywiście sprawa jak zwykle idzie o zasięg zmiennych. Otóż są one dostępne w całym skrypcie.
Dlaczego więc autorzy tak dbajać o nasze bezpieczeństwo naszych skryptów dodali dyrektywe register_globals ??
Otóż dodali oni po to aby zachować zgodność ze starszymi skryptami i dać autorom tych skryptów czas do przemyśleń to (to ja już sobie sam dopowiedziałem). Dyrektywa ta jest domyślnie wyłączona(nieaktywna) czyli register_globals = off;
EDIT:
Zapomniałbym o przykładach w końcu z przykładów człowiek najlepiej się uczy. Wyobraźmy sobie, że wielka firma zleca p. Kowalskiemu napisanie "skryptu strony" opartego o funkcje include() , czyli np. po nadaniu odpowiedniej wartości zmiennej przekazywanej metodą GET powinna nam się ujrzeć odpowiednio includ -owana treść lub wykonany kod. Odrazu więc pan Kowalski zabierze się do pracy pisząc coś takiego :
Kod: Zaznacz cały
// Skrypt strony by Jan Kowalski
if( $strona == 'o_nas' )
{
include('o_nas.php');
}
else
if( $strona == 'promocje' )
{
include('promocje.php');
}
else
{
include('index.php');
}
Odrazu więc niczym szalony poprawia skrypt na zgodny z zaleceniami autorów php, czyli :
Kod: Zaznacz cały
// Skrypt strony by Jan Kowalski
$strona = $_GET['strona'];
if( $strona == 'o_nas' )
{
include('o_nas.php');
}
else
if( $strona == 'promocje' )
{
include('promocje.php');
}
else
{
include('index.php');
}
EDIT 2 :
Postanowiłem dodać jeszcze troche przykładów.
Przykład nr. 2 :
Kod: Zaznacz cały
// Formularz by Jan Kowalski
if( !empty($autor) && !empty($wpis) )
{
// kod właściwy księgi gości
}
else
{
echo '<form>
<input><br>
<textarea></textarea></form>';
}
Kod: Zaznacz cały
// Formularz by Jan Kowalski
if( !empty($_POST['autor']) && !empty($_POST['wpis']) )
{
// kod właściwy księgi gości
}
else
{
echo '<form>
<input><br>
<textarea></textarea></form>';
}
Przykład nr.3
Kod: Zaznacz cały
$ip = $REMOTE_ADDR
Kod: Zaznacz cały
$ip = $_SERVER['REMOTE_ADDR'];
Dla dociekliwych :
http://wiki.php.pl/index.php/Czemu_nie_ ... gradzie%3F
http://pl2.php.net/manual/pl/language.v ... .scope.php
http://pl2.php.net/manual/pl/language.v ... efined.php
http://php.faq.pl/klucz/global
http://forum.webhelp.pl/faqforum.php?f=1#34
Poprawki : Gacek , rzymek01
W razie pytań prosze nie pisać nowych postów pod tym FAQ lecz porozumieć się ze mną za pomocą PW, ponieważ robi się to nie czytelne a chyba nie o to chodzi.