2013-02-23 9 views
11

Ich habe ein Symfony2-Formular erstellt und an die Anfrage gebunden. Ich muss explizit sicherstellen, dass das CSRF-Token gültig/ungültig ist, bevor Sie mit dem Rest des Formulars fortfahren.Wie kann ich überprüfen, ob das angegebene CSRF-Token in Symfony2 ungültig ist?

$form['_token']->isValid() wirft OutOfBoundsException mit Nachricht "Child _token existiert nicht."

Ich kann immer noch überprüfen, dass das gerenderte Formular enthält _token Feld. Falls der CSRF-Wert ungültig ist, gibt $form->isValid() false zurück.

Was fehlt mir hier?


Update 1:

Controller (teilweise):

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'); 
    } 
} 

Vorlage

{# 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

fehlt mindestens der Formularcode. – mpm

+0

@mpm, wahr - jetzt vollständiger Code hinzugefügt, um das Problem zu reproduzieren. –

+0

CSRF Token-Validierung erfolgt automatisch http://symfony.com/doc/current/book/forms.html#csrf-protection –

Antwort

10

Es gibt keine dokumentierter Weise csrf Token manuell zu überprüfen. Symfony überprüft automatisch die Anwesenheit und Genauigkeit dieses Tokens. http://symfony.com/doc/current/book/forms.html#csrf-protection

Allerdings gibt es einen csrf Anbieter:

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

und

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

Marks Klassen können CSRF Schutz bieten Sie ein CSRF Token erzeugen kann, die durch die Verwendung Methode generateCsrfToken(). Zu dieser Methode sollten Sie einen Wert übergeben, der für die Seite eindeutig ist, die gegen CSRF-Angriffe gesichert werden soll . Dieser Wert muss nicht unbedingt geheim sein. Implementierungen dieser Schnittstelle sind verantwortlich für das Hinzufügen von mehr geheimen Informationen .

Wenn Sie eine Formularübermittlung gegen CSRF-Angriffe sichern möchten, können Sie eine "Absichts" -Zeichenfolge angeben. Auf diese Weise stellen Sie sicher, dass das Formular nur an Seiten gebunden werden kann, die für das Formular ausgelegt sind. Dies bedeutet, dass dieselbe Intentionszeichenfolge zum Überprüfen des CSRF-Tokens mit isCsrfTokenValid() verwendet wird.

Sie können die Anbieter wie diese Verwendung

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

abrufen dann

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

Validates a CSRF token. 

Parameter string $ Absicht Die Absicht verwendet, verwenden können, wenn die CSRF-Token-String zu erzeugen Der $ Token Vom Browser bereitgestellter Token

Rückgabewert Boolean Ob das Token durch den Browser geliefert wird, korrekt

Sie müssen die Absicht Zeichenfolge, die von dem Formular verwendet, um finde heraus.

Einige interessante Beiträge auf SO:

Symfony CSRF and Ajax

Symfony2 links with CSRF token

+3

Veraltet seit Symfony 2.4, verwenden Sie stattdessen '' 'security.csrf.token_manager'''. http://api.symfony.com/2.7/Symfony/Component/Security/Csrf/CsrfTokenManagerInterface.html –

0

Ich bin nicht sicher, ob dies aber haben Sie den Validator auf einem nicht zugeordneten Feld versucht:

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

Zusätzlich zu Artworkad können Sie eine Absicht angeben:

Zweig:

<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)); 

Oder auch nicht:

Zweig:

<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

Sollte ajax Anfrage das Token neu generieren? – danidacar

+0

Ajax ist das gleiche?! – user3746259

+0

Sie können das Token in Ajax neu generieren und Ihren Eingabewert aktualisieren: 'öffentliche Funktion tokenAction ($ Absicht) {$ csrf = $ this-> get ('security.csrf.token_manager'); $ token = $ csrf-> refreshToken ($ intention); eine neue Antwort ($ token) zurückgeben; } ' –

Verwandte Themen