2013-02-23 11 views
11

Utworzyłem formularz Symfony2 i powiązałem go z Żądaniem. Muszę jednoznacznie upewnić się, że token CSRF jest ważny/nieważny przed przystąpieniem do dalszej części formularza.Jak mogę sprawdzić, czy dostarczony token CSRF jest nieprawidłowy w Symfony2?

$form['_token']->isValid() wyrzuca OutOfBoundsException z komunikatem "Dziecko _token nie istnieje".

Nadal mogę sprawdzić, czy renderowany formularz zawiera pole _token. W przypadku, gdy wartość CSRF jest nieważna, $form->isValid() zwraca wartość false.

Czego mi tu brakuje?


aktualizacji 1:

kontroler (częściowe)

private function buildTestForm() { 
    $form = $this->createFormBuilder() 
      ->add('name','text') 
      ->getForm(); 
    return $form; 
} 

/** 
* @Route("/test/show_form", name="test.form.show") 
* @Method("GET") 
*/ 
public function showFormTest() 
{ 
    $form = $this->buildTestForm(); 
    return $this->render('TestBundle::form_test.html.twig', array('form' => $form->createView())); 
} 

/** 
* @Route("/test/submit_form", name="test.form.submit") 
* @Method("POST") 
*/ 
public function formTest() 
{ 
    $form = $this->buildTestForm(); 
    $form->bind($this->getRequest()); 
    if ($form['_token']->isValid()) { 
     return new Response('_token is valid'); 
    } else { 
     return new Response('_token is invalid'); 
    } 
} 

Szablon

{# Twig template #} 
<form action="{{ path('test.form.submit') }}" method="post" {{ form_enctype(form) }}> 
    {{ form_widget(form) }} 
    <input type="submit" name="go" value="Test Form" /> 
</form> 
+0

brakuje co najmniej kodu formularza. – mpm

+0

@mpm, true - teraz dodano pełny kod, aby odtworzyć problem. –

+0

Sprawdzanie tokenu CSRF odbywa się automatycznie http://symfony.com/doc/current/book/forms.html#csrf-protection –

Odpowiedz

10

nie ma udokumentowanych sposób sprawdzić csrf znacznik ręcznie. Symfony automatycznie sprawdza obecność i dokładność tego tokena. http://symfony.com/doc/current/book/forms.html#csrf-protection

Jednak nie jest dostawcą csrf:

http://api.symfony.com/2.0/Symfony/Component/Form/Extension/Csrf/CsrfProvider/SessionCsrfProvider.html

i

http://api.symfony.com/master/Symfony/Component/Form/Extension/Csrf/CsrfProvider/DefaultCsrfProvider.html

Oznaczenia klas w stanie zapewnić ochronę CSRF można wygenerować CSRF tokena przy użyciu metoda generateCsrfToken(). Do tej metody należy przekazać wartość, która jest unikalna dla strony, która powinna być zabezpieczona przed atakami CSRF pod numerem . Ta wartość niekoniecznie musi być sekretem . Implementacje tego interfejsu są odpowiedzialne za dodawanie kolejnych tajnych informacji.

Jeśli chcesz zabezpieczyć przesyłanie formularzy przed atakami CSRF, numer może zawierać ciąg "zamiaru". W ten sposób upewnisz się, że formularz może być powiązany tylko ze stronami zaprojektowanymi do obsługi formularza, tj. , czyli używają tego samego ciągu intencji do sprawdzania poprawności tokenu CSRF za pomocą metody isCsrfTokenValid().

Można pobierać dostawcy jak ten

$csrf = $this->get('form.csrf_provider'); 

użytku można następnie wykorzystać

public Boolean isCsrfTokenValid(string $intention, string $token) 

Validates a CSRF token. 

Parametry string $ zamiar Intencją używane podczas generowania tokenów ciąg CSRF $ tokena token dostarczany przez przeglądarkę

Powrót Wartość logiczna czy token dostarczany przez przeglądarkę jest poprawne

Trzeba finde się ciąg intencji używany przez formularza.

Kilka ciekawych stanowisk na SO:

Symfony CSRF and Ajax

Symfony2 links with CSRF token

+3

Przestarzałe od Symfony 2.4, zamiast tego użyj '' security.csrf.token_manager'''. http://api.symfony.com/2.7/Symfony/Component/Security/Csrf/CsrfTokenManagerInterface.html –

0

nie jestem tego pewien, ale czy próbowałeś walidatora na niezmapowanego polu:

$violations = $this->get('validator')->validatePropertyValue($entity, '_token', $form['_token']); 
if (count($violations)) { 
    // the property value is not valid 
} 
9

Ponadto do artworkad możesz określić intencję:

Gałązka:

<form method="post"> 
    <input type="text" name="form_name[field]" value="" /> 
    <input type="hidden" name="_csrf_token" value="{{ csrf_token('form_name') }}"> 
</form> 

PHP:

$token = $request->request->get('_csrf_token'); 
$csrf_token = new CsrfToken('form_name', $token); 
var_dump($this->get('security.csrf.token_manager')->isTokenValid($csrf_token)); 

czy nie:

Gałązka:

<form method="post"> 
    <input type="text" name="field" value="" /> 
    <input type="hidden" name="_csrf_token" value="{{ csrf_token('') }}"> 
</form> 

PHP:

$token = $request->request->get('_csrf_token'); 
$csrf_token = new CsrfToken('', $token); 
var_dump($this->get('security.csrf.token_manager')->isTokenValid($csrf_token)); 
+0

Czy prośba ajax powinna odnawiać token? – danidacar

+0

ajax jest taki sam?! – user3746259

+0

Możesz zregenerować token w ajax i zaktualizować swoją wartość wejściową: 'publiczna funkcja tokenAction (intencja $) {$ csrf = $ this-> get ('security.csrf.token_manager'); $ token = $ csrf-> refreshToken (zamiar $); return new Response ($ token); } ' –

Powiązane problemy