Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Token dla csrf
Forum PHP.pl > Forum > PHP
marcio
Witam mam taki glupi problem oto maja taki kod:
http://pyp.net.pl/source/4f1ad742429ff
No i o ile pokazuje nam ze token wygenerowany i wpisany w html jako pole hidden jest taki sam jak ten z sesji przed wyslaniem formularza, to juz po wyslaniu formularza ten z $_POST['token'] zmienia.

Problem banalny ale stwarza mi wiecej problemow niz te bardziej skomplikowane.

Tutaj mozna sobie zobaczyc http://marcio.ekmll.com/formbuilider/index...news&id=301
login: ebreo
pass: qwerty
szmerak
Ty wogóle nie przekazujesz nigdzie tokena.
Żadnego inputa nie ma.

Mam nadzieje że o to ci chodzi.
Pozdrawiam.
mortus
@szmerak: Jak to nie ma?

@marcio: Zastanów się, czy w dobrym miejscu generujesz token. Zauważ, że w tej chwili każde przeładowanie strony (czy to odświeżenie, czy zatwierdzenie formularza) powoduje wykonanie tej linijki kodu:
  1. $token = $this -> security -> csrf_token_generate();

Natomiast sprawdzenie formularza następuje później i zawsze.
Algorytm powinien być raczej inny:
1. sprawdź, czy zatwierdzono formularz, jeśli tak to 2, jeśli nie to 5
2. sprawdź czy csrf się zgadza, jeśli tak to 3, jesli nie to 4,
3. update, powrót do poprzedniej strony
4. wyświetl błędy, idź do 5
5. wygeneruj csrf i wyświetl formularz
To w dużym uproszczeniu.

EDIT: Zapomniałem o jeszcze jednej ważnej kwestii. Chodzi o to, czym mianowicie jest $this->security, bo mogę jedynie zgadywać. W każdym bądź razie istotnym jest, aby ten obiekt (bo chyba to jest obiekt) przechowywał wygenerowany token np. w sesji czy w bazie danych. Mam nadzieję, że to robi, bo inaczej to nie mamy o czym rozmawiać wink.gif
marcio
Cytat(szmerak @ 21.01.2012, 20:47:43 ) *
Ty wogóle nie przekazujesz nigdzie tokena.
Żadnego inputa nie ma.

Mam nadzieje że o to ci chodzi.
Pozdrawiam.

Tak jak napisal @mortus prosze najpierw dobrze sprawdzic i pozniej ewentualnie wyciagac wnioski.

@mortus masz racje ze generowanie powinno byc w czasie wysylania formularza bo tak jak mowisz token w moim przypadku bedzie generowal sie x2, w czasie ladowania formularza i w czasie jego wyslania zgadzam sie.

Ale wtedy musze recznie ustawic token jesli mam go uzyc po wyslaniu formy, nie moge uzyc pola typu hidden do formularza bo formularz jest wyswietlany 1 raz przed jego wyslalniem potem nie tworze juz formularza.

Czyli mam:
  1. //tworzenie pola typu hidden dla tokenu
  2. $this -> form_builider -> add_field('token');
  3. $this -> form_builider -> set_token_value($token);
  4. $this -> form_builider -> add_form_action(array('action' => 'update_'.$table));

A dopiero potem:
  1. if(isset($_POST['submit_formy']))
  2. {
  3. //walidacja,zapis itp...itd...
  4. }

Czyli musze to zrobic bez niewidocznego pola.

Cytat
EDIT: Zapomniałem o jeszcze jednej ważnej kwestii. Chodzi o to, czym mianowicie jest $this->security, bo mogę jedynie zgadywać. W każdym bądź razie istotnym jest, aby ten obiekt (bo chyba to jest obiekt) przechowywał wygenerowany token np. w sesji czy w bazie danych. Mam nadzieję, że to robi, bo inaczej to nie mamy o czym rozmawiać

Pewnie to jest oczywiste wink.gif
  1. /**
  2. *Generuje token dla csrf
  3. *@access public
  4. *@return string
  5. */
  6. public function csrf_token_generate()
  7. {
  8. if($this -> is_csrf())
  9. {
  10. $token = substr(md5(uniqid()), 1, 10);
  11. $_SESSION['token'] = $token;
  12. return $token;
  13. }
  14.  
  15. return null;
  16. }
  17.  
  18.  
  19. /**
  20. *Sprawdza zgodnosc tokenu z get'a z tym z zapisanym w sesji
  21. *@access public
  22. *@return bool
  23. */
  24. public function csrf_check_token()
  25. {
  26. if($this -> csrf)
  27. {
  28. if($_POST['token'] == $_SESSION['token'])
  29. return true;
  30. else
  31. throw new Volta_Admin_Generator_Csrf_Exception("Zly token.");
  32. }
  33.  
  34. return null;
  35. }


Dzieki za odp.
mortus
Może źle się wcześniej wyraziłem, albo źle zinterpretowałeś moją wypowiedź. Schemat ogólny:
  1. $renderForm = true;
  2. if(isset($_POST['submit_form_sbt'])) {
  3. // walidacja, zapis, itd.
  4. // a jeśli wszystko się powiedzie to albo następuje przekierowanie, albo pozostajemy na tej samej stronie, ale już nie renderujemy formularza edycji danych
  5. // jeśli korzystamy z przekierowania to nie ma potrzeby korzystać ze zmiennej $renderForm
  6. if($wszystkoOk) $renderForm = false;
  7. }
  8. if($renderForm) {
  9. // generujemy token i renderujemy formularz
  10. }

Po prostu musisz najpierw sprawdzić, czy formularz już został zatwierdzony i czy został prawidłowo wypełniony, a jeśli nie to wyświetlić formularz i ewentualne błędy.
Musisz tylko zmienić kolejność działań.

EDIT:
To co masz przed instrukcją warunkową (linie 8-23 włącznie)
  1. if(isset($_POST['submit_form_sbt']))

przenieś przed (linia 80)
  1. return $view;

i powinno działać.
marcio
potem cos zdzialam na dniach mam malo czasu, jak juz poprawie dam znac ;]

EDIT:
Wystarczylo zrobic:
  1. if(!isset($_POST['submit_form_sbt']))
  2. $token = $this -> security -> csrf_token_generate();

I juz nie generuje tokena x2 ;p glupie pytanie i jeszcze glupsze rozwiazanie snitch.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.