Protégez vos actions Symfony2

Cet article a été publié depuis plus de 6 mois, cela signifie que le contenu peut ne plus être d'actualité.

Il est parfois excessif de créer un formulaire pour effectuer certaines actions au sein d'une application. Il est alors d'usage d'utiliser un lien HTML permettant d'effectuer ces opérations (c'est par exemple souvent le cas pour supprimer un élément dans une liste). Il est alors important de sécuriser ses actions.

Pour cela, imaginons une liste d'élément s'affichant de la manière suivante :

<table>
  <tr>
    <td>Mon élement 1</td>
    <td><a href="/element/1/delete">Supprimer</a></td>
  </tr>

  <tr>
    <td>Mon élement 2</td>
    <td><a href="/element/2/delete">Supprimer</a></td>
  </tr>
</table>

Bien sûr il ne s'agit là que d'un exemple, et dans une application réelle, il faudrait que l'action de suppression soit effectuée au travers d'une méthode POST ou DELETE.

En supposant qu'il y ait déjà une restriction en fonction des droits de l' utilisateur connecté, nous allons donc protéger cette action d'une attaque de type CSRF. Pour cela nous allons voir comment générer un jeton qui permettra d'identifier la requête qui sera effectuée.

Nous allons donc commencer par créer le jeton dans l'action qui affiche la liste et ajouter la vérification du token dans l'action de suppression :

// src/JDecool/MyBundle/Controller/DemoController.php

public function listAction(Request $request)
{
    // ...
    $token = $this->get('form.csrf_provider')->generateCsrfToken('element_list');

    return $this->render('MyBundle::list.html.twig', [
        // ...
        'token' => $token,
    ]);
}

public function deleteAction(Request $request, $id)
{
    if (!$this->get('form.csrf_provider')->isCsrfTokenValid('element_list', $token)) {
        $this->redirect('message_list');
    }

    // ...
}

Une fois ce code ajouté, il ne restera plus qu'à passer le jeton lors de la génération du lien de l'action.

Notez également que le jeton généré ici restera valide pour l'ensemble de la durée de la session de l'utilisateur et qu'il pourra être réutilisé. Le jeton est également généré à l'aide du paramètre secretprésent dans le fichier app/config/parameters.yml d'où l'importance de modifier ce dernier.

C'est une méthode simple et rapide qui vise à protéger votre application, et pourtant peu de développeurs l'utilise.