Strona 1 z 2

register_globals=off ... szkoła poprawnego pisania skrypt

: 17 paź 2005, 22:27:10
autor: swpok
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 :

Kod: Zaznacz cały

if( $haslo == 'haslo' ) 
{
  $autoryzacja = 1; 
}
if( $autoryzacja == 1 ) 
{
  echo 'Tajna tresc';
}
 
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 :

Kod: Zaznacz cały

$haslo =  $_POST['haslo']
if( $haslo == 'haslo' ) 
{
  $autoryzacja = 1; 
}
if( $autoryzacja == 1 ) 
{
  echo 'Tajna tresc';
}
 
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 :

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');
}
 
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 :

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>';
&#125;
 
¬LE - powyższy przykład jest źle napisany

Kod: Zaznacz cały

// Formularz by Jan Kowalski
if&#40; !empty&#40;$_POST['autor']&#41; && !empty&#40;$_POST['wpis']&#41; &#41; 
&#123;
// kod właściwy księgi gości 
&#125;
else
&#123;
echo '<form>
<input><br>
<textarea></textarea></form>';
&#125;
 
DOBRZE - powyższy przykład jest dobrze napisany

Przykład nr.3

Kod: Zaznacz cały

$ip = $REMOTE_ADDR
¬LE - powyższy przykład jest źle napisany

Kod: Zaznacz cały

$ip = $_SERVER['REMOTE_ADDR']; 
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.

Re: register_globals=off ... szkoła poprawnego pisania skr

: 06 mar 2006, 16:50:00
autor: rzymek01
swpok pisze:

Kod: Zaznacz cały

// Formularz by Jan Kowalski
if&#40;$_POST['autor'] && $_POST['wpis']&#41; 
&#123;
// kod właściwy księgi gości
&#125;
else
&#123;
echo '<form method="post" action="">
<input type="text" name="autor" /><br />
<textarea name="wpis"></textarea></form>';
&#125;
 
przy pierwszej odsłonie strony lub wtedy, kiedy nie zostaną wysłane dane $_POST, powyższy przykład wyświetli błąd (na niektórych konfiguracjach serwera takie błędy się nie wyświetlają - wtedy można na początku dokumentu dać `error_reporting(E_ALL);`). Aby tego uniknąć należy, a wręcz trzeba stosować funkcje typu empty(), !empty(), isset(), !isset(), a także w szczególności przy formularzach w należy używać funkcji typu is_numeric(), is_array(), is_bool() w celu sprawdzania poprawności danych.

Poprawna forma:

Kod: Zaznacz cały

// Formularz by Jan Kowalski
if&#40;!empty&#40;$_POST['autor']&#41; && !empty&#40;$_POST['wpis']&#41;&#41; 
&#123;
// kod właściwy księgi gości 
&#125;
else
&#123;
echo '<form method="post" action="">
<input type="text" name="autor"/><br/>
<textarea name="wpis"></textarea></form>';
&#125;
 
Wszystkie podane tu funkcje są opisane na `php.net` (jest tam więcej funkcji typu is_*) 8)

: 06 mar 2006, 18:00:20
autor: swpok
Heh, brawo dla tego pana [;
Parser przy konfiguracji E_ALL, rzeczywiście wyświetli błąd. Dzieje się tak dlatego, że nie zdenifiowaliśmy wcześniej wartości dla tego klucza w tablicy superglobalnej.
Tak apropos to nie wiedziałem że !empty() i !isset() to oddzielne funkcje o_O. Przecież to najzwyklejsza w świecie negacja, a że twórcy PHP tak pozwolili ją pisać to może ktoś wziąść to za funkcje. Chyba, że miałeś coś innego na myśli.

Podsumowując plus ci się należy jak najbardziej.

: 09 mar 2006, 21:47:20
autor: rzymek01
oczywiście, że nie istnieje funkcja !empty tylko empty, ale piszę tak w skrócie - uważam, że każdy wie o co chodzi :)

Re: register_globals=off ... szkoła poprawnego pisania skrypt

: 26 paź 2008, 17:48:17
autor: Abaddor
Witam

Dopiero zaczynam przygodę z PHP. I właśnie mam problem tymi zmiennymi globalnymi.
Otóż na swoim domowym serwerze mam następujący kod:

Na 1 stronie mam wypisanie wszystkich danych z SQL, podam kluczowy dla sprawy kod:

Kod: Zaznacz cały

$id=$rekord['ID'];

echo("<a href='tutorial.php?id_numer=$id'<font color='red'><b>$tytul</b><br></font></a>");
 
Podaje do linku id_numer wartość.

Na stronie 2 mam:

Kod: Zaznacz cały

$id = $id_numer;
$wynik=mysql_query("SELECT *  FROM tutoriale WHERE ID=$id")
 
I potem dalej wyświetlanie informacji.

Na moim serverze działa, na CBA już nie. Sprawdziłem że na CBA $id nie ma wartości żadnej czyli link z parametrem nie przekazuje. Wyczytałem że to wina zmiennych globalnych. Ale np. CMS php fusion też używa tego sposobu co ja i działa:|

Na stronie nie mam formularzy więc metody POST i GET odpadają.

Moje pytanie brzmi:

1. Czy mogę włączyć zmienne globalne dla swojej strony?

2. Jeśli nie to jak mam przekazać parametr linkiem do 2 strony?


Kod dawaj w
[code], a nie w [quote]![/color]

Re: register_globals=off ... szkoła poprawnego pisania skrypt

: 26 paź 2008, 17:52:53
autor: Webdesigner
1. Nie.
2.

Kod: Zaznacz cały

$id = $_GET['id']; 

Re: register_globals=off ... szkoła poprawnego pisania skrypt

: 26 paź 2008, 18:07:00
autor: Abaddor
IAHHAHA działa, thx:D

Ale z drugiej strony nie mam sie co cieszyć:|

Odwieczne pytanie:
Dlaczego?

Ja sie dopiero uczę php(umiem C++/WinApi) i myślałem że tablica $_GET[''] tworzy sie kiedy ktoś w zrobi formularz i zastosuje w nim metodę GET.

Nauka to zrozumienie, a nie zrobienie, więc możesz mi wytłumaczyć średnio fachowym językiem?

Re: register_globals=off ... szkoła poprawnego pisania skrypt

: 26 paź 2008, 18:09:14
autor: fuma
metoda GET pozwala Tobie na przekazywanie zmiennych i ich wartosci poprzez adres url a nie koniecznie przez formularz. To metoda POST jest stworzona dla formularzy.

Re: register_globals=off ... szkoła poprawnego pisania skrypt

: 26 paź 2008, 18:15:57
autor: Abaddor
I wszystko jasne.

Bardzo dziękuję za pomoc, bez ciebie bym całą noc myślał jak to zrobić:D

Re: register_globals=off ... szkoła poprawnego pisania skr

: 22 mar 2011, 01:22:38
autor: siodmy
rzymek01 pisze: należy, a wręcz trzeba stosować funkcje typu empty(), !empty(), isset(), !isset()[/b]... w celu sprawdzania poprawności danych.
gwoli scislosci.Te dwie f. nie sa takie same.czesto mylnie brane jako to samo

Re: register_globals=off ... szkoła poprawnego pisania skry

: 28 sie 2012, 18:32:13
autor: Herakles
$strona = $_GET['strona'];

to jest błąd trzeba najpierw sprawdzić czy istnieje to GET
najlepiej skorzystać z zmiennej warunkowej


$zmienna = warunek ? prawda : fałsz;

przykład


$strona = isset($_GET['strona']) ? $_GET['strona'] : ''

nie ma błędów

Re: register_globals=off ... szkoła poprawnego pisania skry

: 06 wrz 2012, 10:24:26
autor: filutek
Stosowanie $_GET ma tą wade że czasem pojawia się potrzeba zmiany np metody w formularzu. Bezpieczniej jest stosować $_REQUEST

a co do sprawdzania czy zmienna jest to zawsze można zrzutować na string i tez działa

BTW czy wie ktoś czemu import_request_variables zostało wyłączone przez zespół PHP?

Re: register_globals=off ... szkoła poprawnego pisania skry

: 06 wrz 2012, 13:27:10
autor: svang
:lol:
jak archeologiści reklamują swoje stopki :lol:

Re: register_globals=off ... szkoła poprawnego pisania skry

: 12 wrz 2012, 19:41:16
autor: Herakles
owszem można użyć czegoś takiego

$temp = $_REQUEST['s'];

lub inaczej:

if (isset($_GET['s'])) {
$temp = $_GET['s'];
}
else {
$temp = $_POST['s'];
}

Re: register_globals=off ... szkoła poprawnego pisania skrypt

: 10 kwie 2014, 13:40:49
autor: Bettye2818
Dzień dobry. Bardzo ciekawi mnie jak to wszystko działa. Jaka jest kolejność wykonywanych czynności i jakie jest prawdopodobieństwo popełnienia błędu, który rzutuje później na efekty końcowe. Czy ktoś coś wie?

____________________
Zajrzyj na naszą ofertę cegła klinkierowa super oferta!