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

Wszystko o językach skryptowych takich jak PHP i Perl, serwerach WWW, CGI, bazach danych i języku SQL.
Awatar użytkownika
swpok
Posty: 510
Rejestracja: 25 wrz 2005, 13:50:56
Lokalizacja: Syreni gród.
Płeć: Mężczyzna
User Agent: Firefox Windows 1024x768
Kontakt:

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

Post 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
&
#125;
if( $autoryzacja == 1 ) 
{
  
echo 'Tajna tresc';
&
#125;
 

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&
#40; $haslo == 'haslo' ) 
{
  
$autoryzacja 1
&
#125;
if( $autoryzacja == 1 ) 
{
  
echo 'Tajna tresc';
&
#125;
 


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&
#40; $strona == 'promocje' )
{
  
include('promocje.php');
}
else
&
#123;
  
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&
#40; $strona == 'o_nas' )
{
  
include('o_nas.php');
}
else 
if&
#40; $strona == 'promocje' )
{
  
include('promocje.php');
}
else
&
#123;
  
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
&
#123;
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.
Ostatnio zmieniony 29 gru 2006, 11:12:57 przez swpok, łącznie zmieniany 9 razy.
Dzień bez uszczypliwości powinno siê uwa¿aæ dniem straconym.
rzymek01
Posty: 22
Rejestracja: 06 mar 2006, 15:53:49
Płeć: Niewybrana
User Agent: Opera Windows 1280x1024
Kontakt:

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

Post 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)
:mrgreen: Widziałeś ju¿ te strony?
:arrow: Strefa DOWNLOAD: downloadia.[regulamin forum: punkt 2.13]
:arrow: FORUM DOWNLOAD: download.forum.[regulamin forum: punkt 2.13]
Awatar użytkownika
swpok
Posty: 510
Rejestracja: 25 wrz 2005, 13:50:56
Lokalizacja: Syreni gród.
Płeć: Mężczyzna
User Agent: Firefox Windows 1024x768
Kontakt:

Post 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.
Dzień bez uszczypliwości powinno siê uwa¿aæ dniem straconym.
rzymek01
Posty: 22
Rejestracja: 06 mar 2006, 15:53:49
Płeć: Niewybrana
User Agent: Opera Windows 1280x1024
Kontakt:

Post 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 :)
:mrgreen: Widziałeś ju¿ te strony?
:arrow: Strefa DOWNLOAD: downloadia.[regulamin forum: punkt 2.13]
:arrow: FORUM DOWNLOAD: download.forum.[regulamin forum: punkt 2.13]
Awatar użytkownika
Abaddor
Posty: 3
Rejestracja: 26 paź 2008, 17:31:52
Strona na CBA.pl: belikepro.cba.pl
Płeć: Mężczyzna
User Agent: Firefox Windows 1280x800

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

Post 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]
"Jedno jest pewne, a mianowicie to że nic nie jest pewne"
Webdesigner
Posty: 1803
Rejestracja: 26 mar 2008, 15:55:03
Lokalizacja: /dev/null/
Płeć: Mężczyzna
User Agent: Firefox Windows 1440x900

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

Post autor: Webdesigner »

1. Nie.
2.

Kod: Zaznacz cały

$id = $_GET['id']; 
Obrazek
Awatar użytkownika
Abaddor
Posty: 3
Rejestracja: 26 paź 2008, 17:31:52
Strona na CBA.pl: belikepro.cba.pl
Płeć: Mężczyzna
User Agent: Firefox Windows 1280x800

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

Post 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?
"Jedno jest pewne, a mianowicie to że nic nie jest pewne"
Awatar użytkownika
fuma
Przyjaciel CBA
Posty: 11168
Rejestracja: 01 sie 2005, 14:57:56
Lokalizacja: z jajka niespodzianki :P
Płeć: Mężczyzna
User Agent: Opera Windows 1600x1200

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

Post 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.
Awatar użytkownika
Abaddor
Posty: 3
Rejestracja: 26 paź 2008, 17:31:52
Strona na CBA.pl: belikepro.cba.pl
Płeć: Mężczyzna
User Agent: Firefox Windows 1280x800

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

Post autor: Abaddor »

I wszystko jasne.

Bardzo dziękuję za pomoc, bez ciebie bym całą noc myślał jak to zrobić:D
"Jedno jest pewne, a mianowicie to że nic nie jest pewne"
siodmy
Posty: 34
Rejestracja: 21 mar 2011, 20:57:04
Strona na CBA.pl: dublindiamond.cba.pl
Płeć: Niewybrana
User Agent: Opera Windows 1366x768

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

Post 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
Awatar użytkownika
Herakles
Posty: 52
Rejestracja: 12 gru 2010, 08:03:35
Strona na CBA.pl: siejuk.c0.pl
Lokalizacja: hi hi
Płeć: Mężczyzna
User Agent: Opera Mobile Android 320x455
Kontakt:

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

Post 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
Wap: http://wapcio.tk
Małe www: http://siejuk.c0.pl
Katalog mobilnych stron http://wapkatalog.tk
filutek
Posty: 5
Rejestracja: 06 wrz 2012, 10:13:51
Płeć: Niewybrana
User Agent: Firefox Windows

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

Post 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?
Ja tak po cichutku polecę doskonały sklep internetowy, który współtworzę oraz te strony internetowe gdzie znajdziesz nie tylko komercyjną ofertę ale także zestaw biznesowych poradników.
Awatar użytkownika
svang
Posty: 204
Rejestracja: 18 gru 2011, 07:06:53
Płeć: Niewybrana
User Agent: Firefox Windows 1024x768

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

Post autor: svang »

:lol:
jak archeologiści reklamują swoje stopki :lol:
Nie dyskutuj z debilkami w necie,wpierw sprowadzą Cię do swojego poziomu,a potem pokonają doświadczeniem!
Awatar użytkownika
Herakles
Posty: 52
Rejestracja: 12 gru 2010, 08:03:35
Strona na CBA.pl: siejuk.c0.pl
Lokalizacja: hi hi
Płeć: Mężczyzna
User Agent: NetFront mobile 320x455
Kontakt:

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

Post 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'];
}
Wap: http://wapcio.tk
Małe www: http://siejuk.c0.pl
Katalog mobilnych stron http://wapkatalog.tk
Bettye2818
Posty: 4
Rejestracja: 04 kwie 2014, 08:20:20
Strona na CBA.pl: cba
Płeć: Niewybrana
User Agent: Firefox Windows

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

Post 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!
ODPOWIEDZ