1

From here Generate new CSRF token without reloading the entire form I learnt there is a method refreshToken() but how and which part of my code below that I use symfony form component, I should modify with that method to force my form to generate a new csrf each time I load my script?

$csrfStorage = new NativeSessionTokenStorage();
$csrfGenerator = new UriSafeTokenGenerator();
$csrfManager = new CsrfTokenManager($csrfGenerator, $csrfStorage);

$formFactory = Forms::createFormFactoryBuilder()
    ->addExtension(new CsrfExtension($csrfManager))
    ->getFormFactory();


$defaultFormTheme = 'bootstrap_3_layout.html.twig';

$vendorDir = realpath(__DIR__.'/../vendor');
$appVariableReflection = new \ReflectionClass('\Symfony\Bridge\Twig\AppVariable');
$vendorTwigBridgeDir = dirname($appVariableReflection->getFileName());
$viewsDir = realpath('twig');

$twig = new Twig_Environment(new Twig_Loader_Filesystem(array(
    $viewsDir,
    $vendorTwigBridgeDir.'/Resources/views/Form',
)));
$formEngine = new TwigRendererEngine(array($defaultFormTheme), $twig);
$twig->addRuntimeLoader(new \Twig_FactoryRuntimeLoader(array(
    TwigRenderer::class => function () use ($formEngine, $csrfManager) {
        return new TwigRenderer($formEngine, $csrfManager);
    },
)));
$twig->addExtension(new FormExtension());

$translator = new Translator('en');
$twig->addExtension(new TranslationExtension($translator));
$form = $formFactory->createBuilder()
    ->add('task', TextType::class)
    ->add('dueDate', DateType::class)
    ->getForm();

$request = Request::createFromGlobals();
$form->handleRequest();
if ($form->isSubmitted() && $form->isValid()) {
    $data = $form->getData();
    print_r($data);
}

$twig->display('new.html.twig', array(
    'form' => $form->createView(),
));


$csrfManager->refreshToken('form');
$form = $formFactory->createBuilder('Symfony\Component\Form\Extension\Core\Type\FormType', array('task' => 'gggg'),  array('csrf_token_manager' => $csrfManager, 'csrf_token_id' => 'form'))
    ->add('task', TextType::class)
    ->add('dueDate', DateType::class)
    ->getForm();

$twig->display('new.html.twig', array(
    'form' => $form->createView(),
));

EDIT: Now with the help of answer, it refreshes always, but now the problem is that it is always an invalid form. What wrong I did?

$csrfManager->refreshToken('my_form_id');
$form = $formFactory->createBuilder('Symfony\Component\Form\Extension\Core\Type\FormType', null,  array('csrf_token_manager' => $csrfManager, 'csrf_token_id' => 'my_form_id'))

->add('task', TextType::class)
->add('dueDate', DateType::class)
->getForm();
$request = Request::createFromGlobals();

$form->handleRequest();

if ($form->isSubmitted() && $form->isValid()) {
    $data = $form->getData();
    print_r($data);
} else {
    print("invalid");
}

What should I do as it is always valid even if it is expected to be valid?

EDIT2:

$csrfManager->refreshToken('form');
$form = $formFactory->createBuilder('Symfony\Component\Form\Extension\Core\Type\FormType', array('task' => 'gggg'),  array('csrf_token_manager' => $csrfManager, 'csrf_token_id' => 'form'))
    ->add('task', TextType::class)
    ->add('dueDate', DateType::class)
    ->getForm();

$twig->display('new.html.twig', array(
    'form' => $form->createView(),
));


$request = Request::createFromGlobals();

    $session = New Session();
    $session->set($formToken, $csrfManager->getToken($formToken)->getValue());
    $request->setSession($session);
    $form->handleRequest();


if ($form->isSubmitted() && $form->isValid()) {
    $data = $form->getData();

print_r($data);
} else {
print("invalid");
}
Joe Hark
  • 155
  • 1
  • 3
  • 10

1 Answers1

1
$csrfManager->refreshToken('my_form_id');
$form = $formFactory->createBuilder('Symfony\Component\Form\Extension\Core\Type\FormType', null,  array('csrf_token_manager' => $csrfManager, 'csrf_token_id' => 'my_form_id'))
    ->add('task', TextType::class)
    ->add('dueDate', DateType::class)
    ->getForm();

.....

$request = Request::createFromGlobals();
        $formToken = '_csrf/'.$form->getName();
       // $storage = new NativeSessionStorage();
        $session = New Session();
        $session->set($formToken, $csrfManager->getToken($formToken)->getValue());
        $request->setSession($session);
        $form->handleRequest();
        dump($request->getSession()->all());

To diable the csrf use the option csrf_protection

$form = $formFactory->createBuilder('Symfony\Component\Form\Extension\Core\Type\FormType', null,  array('csrf_protection' => false))
        ->add('task', TextType::class)
        ->add('dueDate', DateType::class)
        ->getForm();

EDIT : Setting the session

use Symfony\Component\HttpFoundation\Session\Session;
....

    $request = Request::createFromGlobals();
    $formToken = '_csrf/'.$form->getName();
    $session = New Session();
    $session->set($formToken,$csrfManager->getToken($formToken)->getValue());
    $request->setSession($session);
    $form->handleRequest();
Mohamed Ben HEnda
  • 2,686
  • 1
  • 30
  • 44
  • Thanks. Please explain 'csrf_token_id' => 'my_form_id' what my_form_id is? is it the same as id in
    tag? Then in controller $form->isValid() is responsible to check the form?
    – Joe Hark Nov 12 '17 at 14:59
  • The csrf_token_id option is optional but greatly enhances the security of the generated token by making it different for each form. – Mohamed Ben HEnda Nov 12 '17 at 15:08
  • I edit my answer, by adding setting the session which contains the token. dump($request->getSession()->all()) will diplay all sessions attributes (if you doesn't use var_dumper component use var_dump instead of dump) – Mohamed Ben HEnda Nov 12 '17 at 15:11
  • please also advise how to disable the csrf in my code? – Joe Hark Nov 12 '17 at 15:25
  • refreshing works fine. but it doesn't validated the form. Please see "edit" part of my question. I appreciate your advise. – Joe Hark Nov 12 '17 at 15:55
  • Please see "edit" part of my question and advise about form isValid if statement problem. it refreshes csrf but the form is invalid. – Joe Hark Nov 12 '17 at 16:12
  • have you setting the session in the request $request->setSession($session);? – Mohamed Ben HEnda Nov 12 '17 at 16:15
  • Yes, I did but no success. Please see "EDIT2" and advise. I appreciate it. – Joe Hark Nov 12 '17 at 16:20
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/158804/discussion-between-mohamed-ben-henda-and-joe-hark). – Mohamed Ben HEnda Nov 12 '17 at 16:22