Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [TUT]Jak zabezpieczyć formularz przed proxy?
Forum PHP.pl > Forum > PHP
jackraymund
Pewnie dużo osób się zastanawiało jak zabezpieczyć się przed proxy. Dzisiaj jakoś mnie natchnienie wzięło i przeszukałem zmienną globalną $_SERVER i znalazłem kilka wpisów które różnią się od normalnego wejścia, a wejścia z proxy.
Kod pozwoli ci się zabezpieczyć przed proxy typu Hitfaker i HTTP.
  1. $_SERVER['SERVER_PROTOCOL'] - pokazuje protokoł przeglądarki
  2. $_SERVER['HTTP_CONNECTION'] - sam nie wiem
  3. $_SERVER['HTTP_ACCEPT_LANGUAGE'] - zwraca język danej przeglądarki
  4. $_SERVER['HTTP_ACCEPT_ENCODING']- zwraca szyfrowanie(ewentualnie)

To są te zmienne.
I teraz jak to zastosować w praktyce?
No tak! Możemy użyć prostych if'ów(zapytań).
Najpierw zamienimy zmienne globalne w lokalne i wszystko damy sobie w funkcje aby kod był bardziej przejrzysty.
  1. function wykryj(){
  2. $proto = $_SERVER['SERVER_PROTOCOL'];
  3. $conn = $_SERVER['HTTP_CONNECTION'];
  4. $langua = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
  5. $accept = $_SERVER['HTTP_ACCEPT_ENCODING'];
  6. }

Teraz stworzymy jądro skryptu(ify).
No to najpierw zrobimy trudniejsze zapytanie. Zajmiemy się zmienną $_SERVER['HTTP_ACCEPT_ENCODING']
  1. function wykryj(){
  2. $proto = $_SERVER['SERVER_PROTOCOL'];
  3. $conn = $_SERVER['HTTP_CONNECTION'];
  4. $langua = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
  5. $accept = $_SERVER['HTTP_ACCEPT_ENCODING'];
  6. $proxy = 0;
  7. // zmienna która będzie zwracać funkcja
  8. $aha = "gzip";
  9. $strpos = strpos($accept,$aha);
  10. // funkcja szuka w stringu jeżeli go nie znajdzie to zwróci false
  11. if($strpos === false){
  12. $proxy = 1;
  13. }
  14. }

To teraz dodamy zmienną $_SERVER['SERVER_PROTOCOL']. Na zwykłych przeglądarkach zwraca on HTTP/1.1 . Na proxy zwraca czasami HTTP/1.0 . Więc to już cos smile.gif
  1. function wykryj(){
  2. $proto = $_SERVER['SERVER_PROTOCOL'];
  3. $conn = $_SERVER['HTTP_CONNECTION'];
  4. $langua = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
  5. $accept = $_SERVER['HTTP_ACCEPT_ENCODING'];
  6. $proxy = 0;
  7. // zmienna która będzie zwracać funkcja
  8. $aha = "gzip";
  9. $strpos = strpos($accept,$aha);
  10. // funkcja szuka w stringu jeżeli go nie znajdzie to zwróci false
  11. if($strpos === false){
  12. $proxy = 1;
  13. }
  14. elseif($proto != "HTTP/1.1")
  15. {
  16. $proxy = 1;
  17. }
  18. }

Dobra, dodaliśmy 2 zabezpieczenia, zostały ostatnie 2. Zrobimy Connection(normalnie zwraca "Keep-Alive", na proxy albo nic nie zwróci lub "close") i LANGUAGE(Zwraca język przeglądarki).
  1. function wykryj(){
  2. $proto = $_SERVER['SERVER_PROTOCOL'];
  3. $conn = $_SERVER['HTTP_CONNECTION'];
  4. $langua = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
  5. $accept = $_SERVER['HTTP_ACCEPT_ENCODING'];
  6. $proxy = 0;
  7. // zmienna która będzie zwracać funkcja
  8. $aha = "gzip";
  9. $strpos = strpos($accept,$aha);
  10. // funkcja szuka w stringu jeżeli go nie znajdzie to zwróci false
  11. if($strpos === false){
  12. $proxy = 1;
  13. }
  14. elseif($proto != "HTTP/1.1")
  15. {
  16. $proxy = 1;
  17. }
  18. elseif($conn == ""){
  19. $proxy = 1;
  20. }
  21. elseif($langua == ""){
  22. $proxy = 1;
  23. }
  24. }

I można powiedzieć że to już koniec, jeszcze dodamy return i upiększymy trochę kodzik.
  1. function wykryj(){
  2. $proto = $_SERVER['SERVER_PROTOCOL'];
  3. $conn = $_SERVER['HTTP_CONNECTION'];
  4. $langua = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
  5. $accept = $_SERVER['HTTP_ACCEPT_ENCODING'];
  6. $proxy = 0;
  7. // zmienna która będzie zwracać funkcja
  8. $aha = "gzip";
  9. $strpos = strpos($accept,$aha);
  10. // funkcja szuka w stringu jeżeli go nie znajdzie to zwróci false
  11. if($strpos === false){
  12. $proxy = 1;
  13. }
  14. elseif($proto != "HTTP/1.1")
  15. {
  16. $proxy = 1;
  17. }
  18. elseif($conn == ""){
  19. $proxy = 1;
  20. }
  21. elseif($langua == ""){
  22. $proxy = 1;
  23. }
  24. return $proxy;
  25. }

Pamiętajcie aby użyć elseif a nie dawać kolejne if'y. Zwykłymi ifami dałoby rade lecz po co sobie utrudniać życie.
To zostało nam tylko użyć naszej funkcji.
  1. function wykryj(){
  2. $proto = $_SERVER['SERVER_PROTOCOL'];
  3. $conn = $_SERVER['HTTP_CONNECTION'];
  4. $langua = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
  5. $accept = $_SERVER['HTTP_ACCEPT_ENCODING'];
  6. $proxy = 0;
  7. // zmienna która będzie zwracać funkcja
  8. $aha = "gzip";
  9. $strpos = strpos($accept,$aha);
  10. // funkcja szuka w stringu jeżeli go nie znajdzie to zwróci false
  11. if($strpos === false){
  12. $proxy = 1;
  13. }
  14. elseif($proto != "HTTP/1.1")
  15. {
  16. $proxy = 1;
  17. }
  18. elseif($conn == ""){
  19. $proxy = 1;
  20. }
  21. elseif($langua == ""){
  22. $proxy = 1;
  23. }
  24. //tutaj ew. można napisać co ma zrobić jak nie będzie proxy
  25. $t = $_SERVER['REMOTE_ADDR'];
  26. $cz = gethostbyaddr($_SERVER['REMOTE_ADDR']);
  27. $temp = mysql_query("INSERT INTO `lnazwa bazy`.`nazwa tabeli` (
  28. `SERVER_PROTOCOL` ,
  29. `REMOTE_ADDR` ,
  30. `HOST` ,
  31. `HTTP_CONNECTION`,
  32. `HTTP_ACCEPT_ENCODING`,
  33. `HTTP_ACCEPT_LANGUAGE`,
  34. `proxy`
  35. )
  36. VALUES (
  37. '$proto', '$t', '$cz', '$conn','$langua','$accept','$proxy'
  38. );") or die(mysql_error());
  39.  
  40. return $proxy;
  41. }
  42.  
  43.  
  44.  
  45. $wyk = wykryj();
  46. if($wyk == 0){
  47. echo "Nie wykryto proxy";
  48. }
  49. else
  50. {
  51. echo "WYKRYTO PROXY";
  52. }
  53.  

Można też zrobić tak(sposób Pawel_W)
  1. function wykryj(){
  2. $proto = $_SERVER['SERVER_PROTOCOL'];
  3. $conn = $_SERVER['HTTP_CONNECTION'];
  4. $langua = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
  5. $accept = $_SERVER['HTTP_ACCEPT_ENCODING'];
  6. $proxy = 0;
  7. // zmienna która będzie zwracać funkcja
  8. $aha = "gzip";
  9. $strpos = strpos($accept,$aha);
  10. // funkcja szuka w stringu jeżeli go nie znajdzie to zwróci false
  11. if($strpos === false || $proto != "HTTP/1.1" || $p == "" || $s == ""){
  12. $proxy = 1;
  13. }
  14. //tutaj ew. można napisać co ma zrobić jak nie będzie proxy
  15. $t = $_SERVER['REMOTE_ADDR'];
  16. $cz = gethostbyaddr($_SERVER['REMOTE_ADDR']);
  17. $temp = mysql_query("INSERT INTO `lnazwa bazy`.`nazwa tabeli` (
  18. `SERVER_PROTOCOL` ,
  19. `REMOTE_ADDR` ,
  20. `HOST` ,
  21. `HTTP_CONNECTION`,
  22. `HTTP_ACCEPT_ENCODING`,
  23. `HTTP_ACCEPT_LANGUAGE`,
  24. `proxy`
  25. )
  26. VALUES (
  27. '$proto', '$t', '$cz', '$conn','$langua','$accept','$proxy'
  28. );") or die(mysql_error());
  29.  
  30. return $proxy;
  31. }
  32.  
  33.  
  34.  
  35. $wyk = wykryj();
  36. if($wyk == 0){
  37. echo "Nie wykryto proxy";
  38. }
  39. else
  40. {
  41. echo "WYKRYTO PROXY";
  42. }
  43.  

Mój system na 3 240 proxy przepuścił tylko jedno, więc to już coś smile.gif
Podziękowania dla Pigola który pomógł mi w tym temacie wink.gif Temat: Szukanie w stringu danego tekstu
Zdjęcia bazy


A tutaj krótki filmik smile.gif
http://www.youtube.com/watch?v=eLT1aJSyBiE
po chwili(rezultat bombardowania proxami)
http://www.youtube.com/watch?v=r-15YK5nAHw
Jestem nowy w php więc jeżeli coś jest nie tak to prosiłbym o poprawienie.
Fajnie gdyby temat został podpięty, mało osób wie jak się zabezpieczyć "porządnie" przed proxy.
Kod i tutka napisałem samemu, nie pozwalam na kopiowanie.
Pawel_W
nazwy zmiennych typu "iksde", mieszanie polskich nazw z angielskimi, porażka tongue.gif
jackraymund
Mam taki nawyk by nazywać zmienne byle by się nie powtarzały. To też przez inne języki w których programowałem, w dodatku mam 14lat, to też robi swoje.
@down
no niby tak, lecz kto jej nie używa? testowałem na operze, ie, firefox i chrome
@down2
no tak też można by było zrobić lecz nie o to dokładnie mi chodziło przy utrudnianiu życia biggrin.gif(chodziło o elseif'y a if'y)
Pawel_W
wiem, ale jak już dajesz coś do oceny, to mógłbyś je nazwać "po ludzku" smile.gif

EDIT:
sam początek kodu - czy wg Ciebie jeżeli przeglądarka nie obsługuje kompresji gzip, to oznacza, że ktoś wchodzi przez proxy? wink.gif

EDIT 2:
Cytat
Pamiętajcie aby użyć elseif a nie dawać kolejne if'y. Zwykłymi ifami dałoby rade lecz po co sobie utrudniać życie.

po co utrudniać sobie życie? wg mnie utrudnianie sobie życia to właśnie taki kod, skoro można:
  1. if($strpos === false || $proto != "HTTP/1.1" || $p == "" || $s == ""){
  2. $proxy = 1;
  3. }
denis94
A tak z ciekawości, w jaki sposób sprawdziłeś skrypt w tych 3 tysiącach proxy? To jakiś program czy może strona? Podziel się jeśli możesz smile.gif
Fifi209
Google -> hitfaker

@edit
Swoją droga robienie dodatkowych zmiennych global -> local jest bez sensu, bo gorzej zorientować się w kodzie.
Dodatkowo funkcja powinna zwracać typ boolean a nie int
Crozin
@jackraymund: Polecam specyfikację protokołu HTTP bo to co tutaj podałeś nie ma kompletnie nic wspólnego z proxy.
by_ikar
Jakiś czas temu też się nad tym zastanawiałem, ale tak na prawdę to taki sposób zadziała tylko częściowo. Bo nagłówki serwer proxy może sobie jak chce wysyłać i tak na prawdę nie musi ich wysłać wcale. A wtedy dostaniesz tylko adres IP serwera z którego przyszedł request. Musiałbyś mieć wtedy adresy IP wszystkich serwerów proxy. A co jeżeli ktoś na cel włamu do ciebie, postawi sobie serwer proxy na jakimś vps? Porzuciłem rozwiązanie problemu w taki sposób, to zwyczajnie jest to nie osiągalne. Nie możesz się opierać na nagłówkach, zwłaszcza tych które są opcjonalne, bo w tych nagłówkach czasami można wysłać wszystko, jak chociażby css, efektem czego takie triki: http://mathiasbynens.be/demo/css-without-html podejrzyj sobie źródło wink.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.