Co jest złego w używaniu $ _REQUEST []?

116

Widziałem tutaj wiele postów mówiących o tym, aby nie używać $_REQUESTzmiennej. Zwykle tego nie robię, ale czasami jest to wygodne. Co jest z tym nie tak?

sprugman
źródło
2
Zobacz powiązane pytania i odpowiedzi: stackoverflow.com/questions/1149118/…
Gordon
2
Od php 5.3 domyślny php.ini mówi, że tylko dane GET i POST są umieszczane w $_REQUEST. Zobacz php.net/request_order Właśnie natknąłem się na tę przerwę w kompatybilności wstecznej, spodziewając się, że znajdą się dane cookie $_REQUESTi zastanawiam się, dlaczego to nie działa! Tak więc największym powodem do unikania używania $ _REQUEST jest teraz, że twój skrypt nie może się ustawić request_order(tak jest PHP_INI_PERDIR), więc zmiana w php.ini może łatwo złamać założenia, na których zbudowany jest twój skrypt. Lepiej umieścić te założenia bezpośrednio w swoim skrypcie.
Darren Cook

Odpowiedzi:

184

Nie ma absolutnie nic złego w przyjmowaniu danych wejściowych z obu $_GETi $_POSTw połączeniu. W rzeczywistości to jest to, co prawie zawsze chcesz robić:

  • w przypadku zwykłego idempotentnego żądania, zwykle przesyłanego przez GET, istnieje możliwość, że ilość żądanych danych nie zmieści się w adresie URL, więc zamiast tego została zmieniona na żądanie POST ze względów praktycznych.

  • w przypadku żądania, które ma rzeczywisty skutek, należy sprawdzić, czy zostało przesłane metodą POST. Ale sposobem na to jest $_SERVER['REQUEST_METHOD']jawne sprawdzenie , a nie poleganie na $_POSTbyciu pustym dla GET. W każdym razie, jeśli jest to metoda POST, nadal możesz chcieć pobrać niektóre parametry zapytania z adresu URL.

Nie, problem $_REQUESTnie ma nic wspólnego z pomieszaniem parametrów GET i POST. Chodzi o to, że domyślnie zawiera również pliki$_COOKIE . A pliki cookie w rzeczywistości nie przypominają parametrów przesyłania formularzy: prawie nigdy nie chcesz traktować ich tak samo.

Jeśli przypadkowo otrzymasz plik cookie ustawiony w Twojej witrynie o tej samej nazwie, co jeden z parametrów formularza, formularze korzystające z tego parametru w tajemniczy sposób przestaną działać poprawnie z powodu wartości plików cookie zastępujących oczekiwane parametry. Jest to bardzo łatwe do zrobienia, jeśli masz wiele aplikacji w tej samej witrynie, i może być bardzo trudne do debugowania, gdy masz tylko kilku użytkowników ze starymi plikami cookie, których nie używasz już więcej kręcenia się i łamania formularzy na różne sposoby nie - ktoś inny może się rozmnażać.

Możesz zmienić to zachowanie na znacznie bardziej rozsądną GP(nie C) kolejność za pomocą konfiguracji request_order w PHP 5.3. Tam, gdzie nie jest to możliwe, osobiście unikałbym $_REQUESTi jeśli potrzebowałbym połączonej tablicy GET + POST, utworzyłbym ją ręcznie.

bobince
źródło
2
Te sytuacje (dane zbyt długie, aby można je było przesłać za pośrednictwem GET) są wyjątkiem, a nie regułą
Ben James
1
Niezła odpowiedź. Zauważyłem również, że w przypadku frameworków takich jak Zend Framework parametry GET i POST są łączone w jeden obiekt żądania. Nigdy nie uderzyło mnie to, dopóki nie przeczytałem twojego postu.
Jay Sidri,
Domyślnie konfiguracja request_order jest ustawiona na „GP” w php.ini od PHP 5.4+, więc powiedziałbym, że idź ... ale jak zawsze, postępuj ostrożnie.
bcmoney,
jeśli $ _POST to a="foo"i $ _COOKIE a="bar", to czy będą tu jakieś zastąpienia / konflikty?
Rust
75

Przekopałem się przez kilka postów na grupach dyskusyjnych na temat PHP Internals i znalazłem interesującą dyskusję na ten temat. Początkowy wątek był o czymś innym, ale uwaga Stefan Esser, a (jeśli nie ) ekspert bezpieczeństwa w świecie PHP okazało dyskusję wobec implikacji bezpieczeństwa za pomocą $ _REQUEST na kilka stanowisk.

Powołując się na Stefana Essera na temat PHP Internals

$ _REQUEST to jedna z największych słabości projektowych w PHP. Każda aplikacja używająca $ _REQUEST jest najprawdopodobniej podatna na problemy z fałszowaniem opóźnionych żądań między witrynami. (Zasadniczo oznacza to, że jeśli np. Istnieje plik cookie o nazwie (wiek), zawsze nadpisze zawartość GET / POST, a zatem niechciane żądania zostaną wykonane)

iw późniejszej odpowiedzi w tym samym wątku

Nie chodzi o to, że ktoś może sfałszować GET, POST; Zmienne COOKIE. Chodzi o to, że pliki COOKIE nadpiszą dane GET i POST w REQUEST.

Dlatego mogłem zainfekować twoją przeglądarkę ciasteczkiem, który mówi np. Action = logout i od tego dnia nie możesz już korzystać z aplikacji, ponieważ REQUEST [akcja] będzie wylogowywać się na zawsze (do momentu ręcznego usunięcia ciasteczka).

A zainfekowanie Cię plikiem COOKIE jest takie proste ...
a) Mogę użyć wulna XSS w dowolnej aplikacji na subdomenie
b) Czy kiedykolwiek próbowałeś ustawić plik cookie dla * .co.uk lub * .co.kr, gdy posiadasz pojedyncza domena?
c) Inne sposoby międzydomenowe ...

A jeśli uważasz, że to nie jest problem, mogę ci powiedzieć, że istnieje prosta możliwość ustawienia np. Pliku cookie * .co.kr, co powoduje, że kilka wersji PHP zwraca tylko białe strony. Wyobraź sobie: tylko jeden plik cookie, aby zabić wszystkie strony PHP w * .co.kr

I ustawiając niedozwolony identyfikator sesji w pliku cookie ważnym dla * .co.kr w zmiennej o nazwie + PHPSESSID = nielegalny , nadal możesz DOS -ować każdą aplikację PHP w Korei, używając sesji PHP ...

Dyskusja trwa przez kilka kolejnych postów i jest interesująca do przeczytania.


Jak widać, głównym problemem z $ _REQUEST jest nie tyle to, że ma dane z $ _GET i $ _POST, ale także z $ _COOKIE. Kilku innych gości na liście zasugerowało zmianę kolejności, w jakiej $ _REQUEST jest wypełniane, np. Wypełnienie go najpierw $ _COOKIE, ale może to prowadzić do wielu innych potencjalnych problemów, na przykład z obsługą sesji .

Możesz jednak całkowicie pominąć $ _COOKIES w globalnej $ _REQUEST, aby nie zostało nadpisane przez żadną z innych tablic (w rzeczywistości możesz ograniczyć to do dowolnej kombinacji jego standardowej zawartości, jak podręcznik PHP dotyczący ustawienia zmiennej_order ini Powiedz nam:

variable_order Ustawia kolejność analizowania zmiennych EGPCS (środowisko, pobieranie, przesyłanie, plik cookie i serwer). Na przykład, jeśli variable_order jest ustawione na "SP", to PHP utworzy superglobale $ _SERVER i $ _POST, ale nie utworzy $ _ENV, $ _GET i $ _COOKIE. Ustawienie na „” oznacza, że ​​nie zostaną ustawione żadne superglobalne.

Ale z drugiej strony możesz również rozważyć całkowite rezygnację z używania $ _REQUEST, po prostu dlatego, że w PHP możesz uzyskać dostęp do środowiska, pobierania, wysyłania, pliku cookie i serwera w ich własnych globach i mieć jeden wektor ataku mniej. Nadal musisz oczyścić te dane, ale to jedna rzecz mniej, o którą musisz się martwić.


Teraz możesz się zastanawiać, dlaczego mimo wszystko $ _REQUEST istnieje i dlaczego nie jest usuwany. Zapytano o to również w PHP Internals. Cytując Rasmusa Lerdorfa o tym, dlaczego istnieje $ _REQUEST? on PHP Internals

Im więcej takich rzeczy usuwamy, tym trudniej jest ludziom szybko przejść na nowsze, szybsze i bezpieczniejsze wersje PHP. To powoduje znacznie więcej frustracji dla wszystkich niż kilka „brzydkich” starszych funkcji. Jeśli istnieje przyzwoity powód techniczny, wydajność lub bezpieczeństwo, musimy się temu dokładnie przyjrzeć. W tym przypadku powinniśmy się przyjrzeć nie temu, czy powinniśmy usunąć $ _REQUEST, ale czy powinniśmy usunąć z niego dane cookie. Wiele konfiguracji już to robi, w tym wszystkie moje, i istnieje silny uzasadniony powód ze względów bezpieczeństwa, aby nie uwzględniać plików cookie w usłudze $ _REQUEST. Większość ludzi używa zmiennej $ _REQUEST na oznaczenie GET lub POST, nie zdając sobie sprawy, że może ona również zawierać pliki cookie i jako tacy złoczyńcy mogą potencjalnie zrobić kilka sztuczek z wstrzyknięciem plików cookie i zepsuć naiwne aplikacje.

W każdym razie, mam nadzieję, że to rzuciło trochę światła.

Gordon
źródło
1
+1 dobrze, aby zobaczyć dyskusję na ten temat ... Myślałem, że zwariowałem!
bobince
2
Myślę, że ta dyskusja była nieco uogólniona. Rzeczywistym problemem jest brak świadomości programisty, a nie istnienie plików cookie w usłudze $ _REQUEST per se. Na przykład ustalony PHPSESSID zostanie zresetowany za pomocą pliku cookie dla każdej domeny przy użyciu współczesnego kodu obsługi sesji. A dla niektórych aplikacji naprawdę pożądane może być nadpisywanie cookie vars żądania (np. Sort_order = ASC przesłania formularz wyszukiwania GET var). Chociaż kodowanie w takim zachowaniu jest bardziej rozsądne.
mario
1
Bardzo obszerny post, to powinna być odpowiedź. Może ludzie boją się długiego postu;)
Dzung Nguyen
Niestety, Rasmus skomentował to w 2009 roku, a mimo to $ _REQUEST jest zasadniczo taki sam teraz, w 2015 roku.
Kzqai,
10

$_REQUESTodnosi się do wszelkiego rodzaju żądań (GET, POST itp.). Jest to czasami przydatne, ale zwykle lepiej jest określić dokładną metodę ($ _GET, $ _POST itp.).

Luca Matteis
źródło
19
Ta odpowiedź opisuje, czym jest $ _REQUEST, ale nie odpowiada na pytanie.
zombat
1
Mówi, że po prostu lepszą praktyką jest wiedzieć, jakiego rodzaju żądanie będzie przychodzić, i zakodować je.
Polaris878
8

$_REQUEST jest ogólnie uważany za szkodliwy z tego samego powodu, z którego transformacje danych o prostej do średniej złożoności są często wykonywane w kodzie aplikacji zamiast deklarowanych w SQL: niektórzy programiści są do niczego.

W związku z tym, jeśli ktoś ma tendencję do używania $_REQUESTwszędzie, mogę zrobić wszystko przez GET, co mogłem przez POST, co oznacza skonfigurowanie<img> tagów w mojej (złośliwej) witrynie, które powodują, że użytkownicy zalogowani do modułu e-commerce po cichu kupują produkty, lub ja może spowodować, że klikną linki, które spowodują niebezpieczne działania lub ujawnią poufne informacje (prawdopodobnie mnie).

Jest to jednak spowodowane tym, że początkujący lub przynajmniej niedoświadczony programista PHP popełnia proste błędy. Po pierwsze, wiedz, kiedy dane jakiego typu są odpowiednie. Na przykład mam usługę internetową, która może zwracać odpowiedzi w URLEncoding, XML lub JSON. Aplikacja decyduje, jak sformatować odpowiedź, sprawdzając nagłówek HTTP_ACCEPT, ale może zostać specjalnie wymuszona przez wysłanieformat parametru.

Podczas sprawdzania zawartości parametru formatu, może on zostać wysłany za pomocą zapytania querystring lub postdata, w zależności od wielu czynników, z których nie najmniejszym jest to, czy wywołujące aplikacje chcą, czy nie chcą „& format = json” zmieszane z żądaniem. W tym przypadku $_REQUESTjest to bardzo wygodne, ponieważ oszczędza mi konieczności wpisywania czegoś takiego:

$format = isset($_POST['format']) ? $_POST['format'] 
    : (isset($_GET['format']) ? $_GET['format'] : null);

Nie będę się dalej rozwodził, ale wystarczy to powiedzieć $_REQUEST nie odradza się używania, ponieważ jest z natury niebezpieczne - to tylko kolejne narzędzie, które robi dokładnie to, o co się go prosi, niezależnie od tego, czy rozumiesz te konsekwencje, czy nie - to jest zła, leniwa lub niedoinformowana decyzja słabego, leniwego lub niedoświadczonego programisty, która powoduje ten problem.

Jak $_REQUESTbezpiecznie używać


  1. Poznaj swoje dane : powinieneś mieć pewne oczekiwania co do tego, jakie dane otrzymasz, więc odpowiednio je oczyść. Dane do bazy danych? addslashes()lub *_escape_string(). Zamierzasz pokazać go użytkownikowi? htmlentities()lub htmlspecialchars(). Oczekujesz danych liczbowych? is_numeric()lub ctype_digit(). W rzeczywistości,filter_input() i powiązane z nim funkcje są przeznaczone tylko do sprawdzania i oczyszczania danych. Zawsze używaj tych narzędzi.
  2. Nie uzyskuj bezpośredniego dostępu do danych superglobalnych podanych przez użytkownika . Wyrób sobie nawyk dezynfekcji danych za każdym razem i przenoś je do czystych zmiennych, nawet jeśli to tylko zwykłe$post_clean . Alternatywnie możesz po prostu wyczyścić bezpośrednio w superglobalnych, ale powodem, dla którego zalecam używanie oddzielnej zmiennej, jest to, że ułatwia to wykrycie luk w kodzie, ponieważ wszystko , co wskazuje bezpośrednio na superglobalny, a nie oczyszczony odpowiednik, jest uważane za niebezpieczny błąd .
  3. Dowiedz się, skąd powinny pochodzić dane. Odwołując się do mojego przykładu z góry, jest całkowicie uzasadnione zezwolenie na wysyłanie zmiennej formatu odpowiedzi za pośrednictwem GET lub POST. Zezwalam również na wysyłanie zmiennej „action” dowolną metodą. Jednak same akcje mają bardzo szczegółowe wymagania co do tego, który czasownik HTTP jest akceptowalny . Funkcje, na przykład zmieniające dane wykorzystywane przez usługę, mogą być przesyłane wyłącznie za pośrednictwem POST. Żądania niektórych typów danych bez uprawnień lub danych o niskim poziomie uprawnień (takich jak dynamicznie generowane obrazy map) mogą być obsługiwane w odpowiedzi na żądania z dowolnej metody.

Podsumowując, pamiętaj o tej prostej zasadzie:

BEZPIECZEŃSTWO TO TY, LUDZIE!

EDYTOWAĆ:

Ja zdecydowanie polecam porady bobince: jeśli możesz, ustawrequest_order parametr w pliku php.ini do „GP”; to znaczy bez składnika cookie. W ponad 98% przypadków nie ma prawie żadnego racjonalnego uzasadnienia, ponieważ dane z plików cookie prawie nigdy nie powinny być uważane za porównywalne z zapytaniem lub postdata.

PS, anegdota!

Znałem programistę, który wymyślił $_REQUESTmiejsce do prostego przechowywania danych, które byłyby dostępne w superglobalny sposób. Ważne nazwy użytkowników i hasła, ścieżki do plików, nadasz im nazwę i zostały zapisane w $_REQUEST. Był trochę zaskoczony (choć nie tak komicznie, niestety), kiedy powiedziałem mu, jak zachowuje się ta zmienna. Nie trzeba dodawać, że ta praktyka została obalona.

Usunięto
źródło
8

Żądania GET powinny być idempotentne, a żądania POST generalnie nie. Oznacza to, że dane $_GETi $_POSTpowinno być ogólnie stosowane w różny sposób.

Jeśli twoja aplikacja korzysta z danych z $_REQUEST, będzie zachowywać się tak samo dla żądań GET i POST, co narusza idempotencję GET.

Ben James
źródło
1
ale czy to nie zależy od implementacji? „Indempotent” to dla mnie nowe słowo, ale jeśli dobrze je rozumiem, łatwo byłoby wyobrazić sobie sytuację GET, która nie byłaby indempotentna. Na przykład liczniki stron generalnie zwiększają się za każdym razem, gdy żądasz danego adresu URL.
sprugman
1
@sprugman - również możesz mieć sytuacje, w których masz zarówno dane GET, jak i dane POST w tym samym żądaniu, w którym to przypadku metoda żądania jest zasadniczo bez znaczenia, gdy jest kontekstualizowana z danymi żądania.
zombat
sprugman, oczywiście każde żądanie GET modyfikuje coś, ponieważ jest rejestrowane przez serwer WWW. W domenie aplikacji nadal może być indempotentny, gdzie metadane nie mają tak naprawdę znaczenia.
Ben James
@sprugman - ogólna idea jest taka, że ​​nie powinieneś mieć żądania GET, które modyfikuje dane. Typowym przykładem tego, dlaczego jest to złe, może być pająk sieciowy indeksujący Twoją witrynę i podążający za linkami, które nieumyślnie modyfikują dane. Na przykład link „flaga” w poście SO.
Eric Petroelje
To był trywialny przykład. Co powiesz na to, że używam GET przez ajax, ponieważ jest szybszy (jak zasugerowano w tym poście na carsonified carsonified.com/blog/dev/the-definitive-guide-to-get-vs-post ).
sprugman
7

To jest niejasne. Tak naprawdę nie wiesz, w jaki sposób dane dotarły do ​​Ciebie, ponieważ zawierają one dane wysyłania, pobierania i plików cookie. Niekoniecznie uważam, że to zawsze jest złe, chyba że musisz znać lub ograniczać sposób dostawy.

Sampson
źródło
3

Właściwie to lubię go używać. Zapewnia elastyczność korzystania z funkcji GET lub POST, co może być przydatne w przypadku formularzy wyszukiwania, w których dane są wysyłane przez większość czasu, ale czasami będziesz chciał powiedzieć link do określonego wyszukiwania, więc możesz zamiast tego użyć parametrów GET .

Ponadto, jeśli spojrzysz na wiele innych języków (na przykład ASP.NET), w ogóle nie rozróżniają zmiennych GET i POST.

ETA :

Nigdy nie użyłem REQUEST, aby uzyskać wartości COOKIE, ale myślę, że Kyle Butt świetnie wypowiada się w komentarzach do tego postu na ten temat. NIE jest dobrym pomysłem używanie REQUEST do pobierania wartości COOKIE. Uważam, że ma rację, że jeśli to zrobisz, istnieje realny potencjał fałszowania żądań między witrynami.

Ponadto kolejność, w jakiej rzeczy są ładowane do REQUEST, jest kontrolowana przez parametry konfiguracyjne w php.ini (variable_order i request_order). Tak więc, jeśli masz tę samą zmienną przekazaną zarówno przez POST, jak i GET, to, która z nich trafia do REQUEST, zależy od tych ustawień ini. Może to wpłynąć na przenośność, jeśli polegasz na określonej kolejności, a te ustawienia są skonfigurowane inaczej niż się spodziewasz.

Eric Petroelje
źródło
to okropny błąd. Jak możesz zagwarantować, że nie idempotentne działania zostały przeprowadzone w POST?
Kyle Butt
1
@Kyle - nie używając go do działań nie idempotentnych. Na pewno nie użyłbym go do wszystkiego, po prostu wskazując, że jest przydatny, na przykład do wyszukiwań, o których wspomniałem w moim przykładzie.
Eric Petroelje
1
Ten magiczny pomysł, że _POST jest bezpieczny, a _GET nie, musi odejść. Jeśli nie używam twojego oprogramowania poprawnie, wtedy istnieje bardzo niewielka (jeśli w ogóle) różnica między wysyłaniem żądania POST a żądaniem GET. Bezpieczeństwo zależy od tego, co robisz z danymi, a nie skąd one pochodzą. Jeśli chodzi o proste exploity XSS / Request, jest całkiem możliwe, że używa on _REQUEST tylko dla wartości, które byłyby prawidłowe z POST lub GET, a _POST używa tylko dla rzeczy, które powinny być POST. Zdrowy rozsądek, a nie magiczne użycie superglobalne.
Wydany
1
@Kyle - Nadal nie rozumiem, jak nie mógłbyś zrobić tego, o czym wspomniałeś, równie łatwo, używając czegoś takiego jak curl () lub post ajax, aby przekazać te same dane przez POST i COOKIE. Niezależnie od tego, czy używasz REQUEST, GET, POST czy COOKIE, wszystkie dane ostatecznie pochodzą od klienta i zawsze można je sfałszować.
Eric Petroelje
1
@zombat: Twoje żądanie curl nie zostanie zalogowane jako użytkownik podatny na ataki. Link, który utworzysz i umieścisz w swojej witrynie, będzie. @Dereleased: To nie jest magiczne myślenie, a GET wciąż ma mnóstwo luk w zabezpieczeniach. ale bezpieczniejsze jest zaufanie POST od zalogowanego użytkownika niż GET od zalogowanego użytkownika.
Kyle Butt
2

Ważne jest, aby zrozumieć, kiedy używać POST, kiedy używać GET i kiedy używać pliku cookie. Dzięki $ _REQUEST wartość, na którą patrzysz, mogłaby pochodzić z dowolnego z nich. Jeśli spodziewasz się uzyskać wartość z POST, GET lub z pliku COOKIE, dla kogoś czytającego Twój kod bardziej pouczające jest użycie określonej zmiennej zamiast $ _REQUEST.

Ktoś inny zwrócił również uwagę, że nie chcesz, aby wszystkie POST lub pliki cookie były zastępowane przez GET, ponieważ istnieją różne reguły między witrynami dla wszystkich z nich, na przykład, jeśli zwracasz dane ajax podczas korzystania z $ _REQUEST, jesteś podatny na ataki do ataku skryptu między lokacjami.

Kyle Butt
źródło
2

Jedyny przypadek, w którym używanie $_REQUESTnie jest złym pomysłem, to GET.

  • Jeśli używasz go do ładowania wartości POST, ryzykujesz fałszerstwami żądań między lokacjami
  • Jeśli używasz go do ładowania wartości plików cookie, ponownie ryzykujesz fałszowaniem żądań między witrynami

A nawet z GET $_GETjest krótszy do wpisania niż $_REQUEST;)

Jani Hartikainen
źródło
Chociaż zgadzam się z tobą, myślę, że ważne jest, aby zauważyć, dlaczego jest to prawdą i / lub niebezpieczną: należy użyć, $_POSTgdy ważne jest, aby dane były POSTDATA. Należy użyć, $_REQUESTgdy dane są niezależne od używanego czasownika HTTP. We wszystkich tych przypadkach należy dokładnie oczyścić wszystkie dane wejściowe.
Wydany
1
Nie rozumiem, jak źródło danych ma się do prawdopodobieństwa fałszowania żądań między witrynami. Atakujący może bardzo łatwo ustawić parametr POST, dostarczając użytkownikowi formularz POST wskazany w Twojej witrynie; będziesz potrzebować tych samych środków ochrony przed XSRF, niezależnie od tego, czy zgłoszenie pochodzi z GET czy POST.
bobince
O wiele łatwiej jest nadużyć GET za fałszerstwo. Na przykład możesz po prostu mieć tag img z ustawionym src z żądanymi parametrami. Będzie działać bez wiedzy użytkownika, że ​​tam jest.
Jani Hartikainen
0

Mogę być używany tylko wtedy, gdy chcesz pobrać aktualny adres URL lub nazwę hosta, ale w przypadku faktycznego analizowania danych z tego adresu URL, takich jak parametry przy użyciu symbolu &, prawdopodobnie nie jest to dobry pomysł. Ogólnie rzecz biorąc, nie chcesz używać niejasnego opisu tego, co próbujesz zrobić. Jeśli chcesz być konkretny, to tam $ _REQUEST jest złe, jeśli nie musisz być konkretny, możesz go użyć. Myślę.

Brian T Hannan
źródło
Co próbujesz powiedzieć? Czy mylisz się $_REQUESTz $_SERVER['QUERY_STRING']?
Wydany
0

Jeśli wiesz, jakich danych potrzebujesz, powinieneś wyraźnie o to poprosić. IMO, GET i POST to dwa różne zwierzęta i nie mogę wymyślić dobrego powodu, dla którego miałbyś kiedykolwiek potrzebować mieszać ciągi danych i zapytań. Jeśli ktoś ma, byłbym zainteresowany.

Użycie zmiennej $ _REQUEST może być wygodne, gdy skrypty mogą odpowiadać na polecenia GET lub POST w ten sam sposób. Twierdziłbym jednak, że powinien to być niezwykle rzadki przypadek, aw większości przypadków preferowane są dwie oddzielne funkcje do obsługi dwóch oddzielnych pojęć lub przynajmniej sprawdzanie metody i wybór właściwych zmiennych. Przebieg programu jest zwykle dużo łatwiejszy do prześledzenia, gdy nie jest konieczne odwoływanie się do źródła pochodzenia zmiennych. Bądź miły dla osoby, która będzie musiała zachować Twój kod za 6 miesięcy. To może być ty.

Oprócz problemów z bezpieczeństwem i WTF spowodowanych przez pliki cookie i zmienne środowiskowe w zmiennej REQUEST (nie zaczynaj od GLOBAL), zastanów się, co mogłoby się stać w przyszłości, gdyby PHP zaczęło natywnie wspierać inne metody, takie jak PUT i DELETE. Chociaż jest bardzo mało prawdopodobne, aby zostały one połączone z superglobalnym REQUEST, możliwe jest, że zostaną włączone jako opcja w ustawieniu variable_order. Więc naprawdę nie masz pojęcia, co zawiera REQUEST i co ma pierwszeństwo, szczególnie jeśli twój kod jest wdrożony na serwerze innej firmy.

Czy POST jest bezpieczniejszy niż GET? Nie całkiem. Lepiej jest używać GET tam, gdzie jest to praktyczne, ponieważ w dziennikach łatwiej jest zobaczyć, w jaki sposób aplikacja jest wykorzystywana, gdy zostanie zaatakowana. POST jest lepszy w przypadku operacji, które wpływają na stan domeny, ponieważ pająki zwykle ich nie śledzą, a mechanizmy pobierania predykcyjnego nie usuwają całej zawartości po zalogowaniu się do systemu CMS. Jednak nie chodziło o zalety GET vs POST, chodziło o to, jak odbiorca powinien traktować przychodzące dane i dlaczego źle je scalać, więc to tak naprawdę tylko BTW.

Duncan
źródło
0

Myślę, że nie ma z tym problemu $_REQUEST, ale musimy zachować ostrożność podczas korzystania z niego, ponieważ jest to zbiór zmiennych z 3 źródeł (GPC).

Myślę, że $_REQUESTjest nadal dostępny, aby uczynić stare programy kompatybilnymi z nowymi wersjami php, ale jeśli zaczniemy nowe projekty (w tym nowe biblioteki), myślę, że nie powinniśmy $_REQUESTjuż używać, aby programy były bardziej przejrzyste. Powinniśmy nawet rozważyć usunięcie zastosowań $_REQUESTi zastąpienie go funkcją opakowującą, aby program był lżejszy, szczególnie w przetwarzaniu dużych przesłanych danych tekstowych, ponieważ $_REQUESTzawiera kopie $_POST.

// delete $_REQUEST when program execute, the program would be lighter 
// when large text submitted
unset($_REQUEST);

// wrapper function to get request var
function GetRequest($key, $default = null, $source = '') 
{
  if ($source == 'get') {
    if (isset($_GET[$key])) { 
      return $_GET[$key]; 
    } else { 
      return $default; 
    }
  } else if ($source == 'post') {
    if (isset($_POST[$key])) { 
      return $_POST[$key]; 
    } else { 
      return $default; 
    }
  } else if ($source == 'cookie') {
    if (isset($_COOKIE[$key])) { 
      return $_COOKIE[$key]; 
    } else { 
      return $default; 
    }
  } else {
    // no source specified, then find in GPC
    if (isset($_GET[$key])) {
      return $_GET[$key];     
    } else if (isset($_POST[$key])) {
      return $_POST[$key]; 
    } else if (isset($_COOKIE[$key])) {
      return $_COOKIE[$key]; 
    } else {
      return $default; 
    } 
  }
}
user953985
źródło
0

Darren Cook: „Ponieważ php 5.3, domyślny php.ini mówi, że tylko dane GET i POST są umieszczane w pliku$_REQUEST . Zobacz php.net/request_order Właśnie natknąłem się na tę przerwę w kompatybilności wstecznej, spodziewając się, że znajdują się dane cookie $_REQUESTi zastanawiam się, dlaczego tak się nie stało” t działa! ”

Wow ... właśnie niektóre z moich skryptów przestały działać z powodu aktualizacji do PHP 5.3 . Zrobiłem to samo: załóżmy, że pliki cookie zostaną ustawione podczas używania $_REQUESTzmiennej. Po aktualizacji dokładnie to przestało działać.

Teraz osobno wywołuję wartości plików cookie za pomocą $_COOKIE["Cookie_name"]...

Arjan202
źródło
-1

Głównym problemem jest to, że zawiera pliki cookie, jak powiedzieli inni.

W PHP 7 możesz to zrobić:

$request = array_merge($_GET ?? [], $_POST ?? []);

Pozwala to uniknąć problemu z plikami cookie i daje w najgorszym przypadku pustą tablicę, aw najlepszym przypadku połączenie $ _GET i $ _POST, przy czym pierwszeństwo ma ta ostatnia. Jeśli nie przejmujesz się zbytnio zezwalaniem na wstrzykiwanie parametrów do adresu URL za pośrednictwem ciągu zapytania, jest to całkiem wygodne.

amh15
źródło
Ci, którzy zdecydują się zagłosować przeciw, proszę o wyjaśnienie mojego podbudowania.
amh15
-2

To bardzo niepewne. Jest to również niezręczne, ponieważ nie wiesz, czy otrzymujesz POST, GET lub inne żądanie. Podczas projektowania aplikacji naprawdę powinieneś znać różnicę między nimi. GET jest bardzo niebezpieczny, ponieważ jest przekazywany w adresie URL i nie nadaje się do prawie wszystkiego poza nawigacją po stronie. POST, choć sam w sobie nie jest bezpieczny, zapewnia jeden poziom bezpieczeństwa.

stan
źródło
4
Nie ma różnicy w bezpieczeństwie między $ _POST a $ _GET, poza tym, że nie możesz wpisać żądania POST w pasku adresu przeglądarki. Jednak wygenerowanie żądania cURL wiersza polecenia przy użyciu POST zajmuje tylko 5 sekund.
zombat
3
@Zombat: Musimy rozpocząć jakąś kampanię, aby przekonać ludzi, że POST nie jest z natury bezpieczny, ani nawet bezpieczniejszy niż GET. Bezpieczeństwo polega na tym, jak traktujesz dane, a nie na tym, jaki czasownik HTTP został użyty, aby je tam dostać.
Wydany
@Dereleased - proponuję ikoniczne, dwukolorowe zdjęcie chmury z kilkoma błyskawicami, które mają reprezentować internet, ze słowem „CHANGE” poniżej.
zombat
1
@GuyT: To bardzo wąski pogląd. Nie chodzi tylko o to, jak jest to „bezpieczne”, ale jak jest to poufne. Parametry GET mogą pojawiać się jako autouzupełnianie w adresie URL przeglądarki, a nawet w historii przeglądarki. Ponadto bezpieczeństwo nie kończy się na przeglądarce. Na przykład wiele serwerów rejestruje adresy URL http, więc na przykład wszystko w adresie URL zostanie zarejestrowane. Pojawienie się nazwy użytkownika / hasła w dziennikach Ma znaczenie. Ze względów bezpieczeństwa zawsze unikaj przekazywania poufnych informacji jako parametrów GET.
stan
1
W szczególności dzienniki dostępu Apache. Każdy adres URL żądania zostanie zarejestrowany, a KAŻDY, kto ma dostęp do dzienników, może zobaczyć przechodzące dane uwierzytelniające.
stan