Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [opinie] request security
Forum PHP.pl > Inne > Oceny
Spawnm
Hej,
luźny temat z pytaniem co myślicie to tej małej klasie:
Jej zadaniem ma być sprawdzenie jeszcze w bootstrapie czy akcje zadań są wykonywane przez usera a nie bota itd.

  1. /**
  2. * @author Spawnm
  3. * @license New BSD License
  4. */
  5. class security_request
  6. {
  7. /**
  8.   * @param array $data
  9.   */
  10. public function initGET(array $data)
  11. {
  12. if($_GET){
  13. foreach($data as $key){
  14. if( isset($_GET[ $key ] ) && !isset($_SERVER['HTTP_REFERER'] )){
  15. throw new Exception('initGET: security failed.');
  16. }
  17. if( isset($_GET[$key]) && !$this->refererIsLocal() ){
  18. throw new Exception('initGET: security failed.');
  19. }
  20. }
  21. }
  22. }
  23.  
  24. /**
  25.   * @return bool
  26.   */
  27. public function refererIsLocal()
  28. {
  29. $host = parse_url($_SERVER['HTTP_REFERER']);
  30. $host = $host['host'];
  31. $local = $_SERVER['HTTP_HOST'];
  32. return ($host === $local )? true : false;
  33. }
  34.  
  35. /**
  36.   * @param array $data
  37.   */
  38. public function initPOST(array $data)
  39. {
  40. if($_POST){
  41. foreach($data as $key){
  42. if( isset($_POST[ $key ] ) && !isset($_SERVER['HTTP_REFERER'] )){
  43. throw new Exception('initPOST: security failed.');
  44. }
  45. if( isset($_POST[$key]) && !$this->refererIsLocal() ){
  46. throw new Exception('initPOST: security failed.');
  47. }
  48. }
  49. }
  50. }
  51.  
  52. }


Demo:
  1. $sec= new security_request();
  2. $sec->initGET(array('delete', 'edit', 'add'));
  3. $sec->initPOST(array('add', 'edit', 'id', 'captcha'));

ShadowD
Ja to specjalistą od php nie jestem i na pewno nie dorastam Ci do pięt, ale czy te informacje nie są łatwe do podrobienia? Bota można łatwo napisać curl'em, dodać odpowiednie nagłówki i inne pierdołki, czy wtedy Twoja klasa nie mija się z przeznaczeniem?

Spawnm
Możliwe, dlatego powstał ten temat smile.gif
Liczę na wasze opinie i rady.
ShadowD
Nie obstawiał bym by dało się wyciąć wszystkie boty które chcą nam namieszać nie utrudniając życia userom, a w szczególności jak sami udostępniamy jakieś api. Jak dla mnie to co pokazałeś jest tylko pierwszym i to malutkim krokiem, nie wiem jaki powinien być następny, ale sprawdzanie ilości operacji strategicznych i zapisywanie ich czasu i maszyny proszącej o wykonanie jej i wycinanie tych które chcą za dużo np. zmiana passów co sekundę, logowanie 10 krotne w ciągu minuty itd powinno pomóc. Temat rzeka i raczej każda możliwość to tylko utrudnienie akcji a nie jej uniemożliwienie - czasem zachodzi pytanie czy jest sens walczyć o wycięcie tych kilku procent lub setnych atakujących nie znających się na podanie nagłówków i zatrudnianie serwera do sprawdzania całej reszty poprawnych żądań.
Rid
Każde zabezpieczenie jest dobre.Jestem laikiem w porównaniu do Pana,ale próbował bym jeszcze przefiltrował porty do tego poprzez:
$_SERVER['REMOTE_PORT']
jako dodatkową metodę.
Nie wiem czy coś to da,ale

public function refererIsLocal()
{
$host = parse_url($_SERVER['HTTP_REFERER']);
$host = $host['host'];
$local = $_SERVER['HTTP_HOST'];
$_SERVER['HTTP_ACCEPT']=$local;
return ($host === $local )? true : false;
}

Może już,nie będę mieszał,fajna klasa,można ją rozbudować o dodatkowe metody.
Crozin
Czyli jeżeli wyłączę sobie wysyłanie nagłówka Referer, to mam pochodzone po stronie? Rzucanie wyjątku klasy Exception, dublowanie kodu, bezsensowne nazewnictwo i kod (ma wywalić wyjątek jeżeli pojawi się element, którego się spodziewam?) czy tworzenie obiektu, który na dobrą sprawę jest funkcją pomijam.

Aha, a to czym powinieneś się zainteresować to atak typu CSRF.
Zyx
Przyglądam się temu listingowi od kilku minut i nie mogę wyjść z podziwu dla ilości bezsensownego kodu, który się w niej znajduje. Spawnm, czy w ogóle zastanowiłeś się nad tym, co chcesz osiągnąć, a co napisałeś? Może się zdziwisz, ale cała ta Twoja powyższa klasa jest równoważna... dwóm ifom:

Kod
if(!isset($_SERVER['HTTP_REFERER'] )){
   throw new Exception('security failed.');
}
if(!$this->refererIsLocal() ){
   throw new Exception('security failed.');
}


Na co Ci te tablice i pętle w środku, kiedy one absolutnie niczemu nie służą? Przecież ten problem jest zupełnie niezależny od tego czy określone pole w $_POST/$_GET istnieje czy nie. Powiem nawet więcej: jeśli dwa pola istnieją, to sprawdzasz w kółko pierdylion razy ten sam warunek, o którym już wiesz, że jest prawdziwy, bo jakby był fałszywy, to by się przy pierwszej iteracji już wysypał.

Osobną kwestią jest sensowność założeń samego zabezpieczenia. Zabezpieczeń nie projektuje się w ten sposób, że myślisz sobie "chcę się zabezpieczyć przed botem", a później wymuszasz na użytkowniku konieczność istnienia losowo wybranego przez Ciebie nagłówka HTTP (w tym przypadku Referer). Co komu szkodzi napisać bota, który ma referera? Co zwykłemu użytkownikowi szkodzi takowy wyłączyć? Pomyślałeś o tym? Chyba nie. Nieuczciwych botów nigdy nie wytniesz, a uczciwym wystarczy plik robots.txt. Bezsensowne jest też użycie programowania obiektowego w tym miejscu i w takiej formie.
Spawnm
Wiem, dziś się obudziłem z podobną myślą.
Ale wczoraj wieczorem wyglądało to jakoś sensowniej i ciekawiej tongue.gif
PawelC
Mi zawsze radzili tak, jak coś napiszesz i będzie Ci się podobało, to odstaw to, prześpij się i zobacz ponownie następnego dnia biggrin.gif hehe
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.