# TP5 : Renforcer la Sécurité des Applications Symfony

> This work is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-nc-sa/4.0/).
> Permission is explicitly granted to copy, distribute and/or modify this document for educational purposes under the terms of the CC BY-NC-SA license.

## Objectifs :

Les objectifs de ce TP sont :

- Renforcer la sécurité d'un projet Symfony existant en mettant en place des mesures contre les menaces courantes
de sécurité web, telles que :
  - le Cross-Site Scripting (XSS),
  - le Cross-Site Request Forgery (CSRF),
  - en permettant l'inscription sécurisée des utilisateurs, leur connexion et déconnexion,
  - et en implémentant l'autorisation des utilisateurs en fonction des rôles.

## Prérequis :

- Un projet Symfony fonctionnel (votre projet `TweetTok`, votre projet Symfony, une SAE).

## Ressources

- [Documentation de Sécurité Symfony](https://symfony.com/doc/current/security.html)

## Partie 1 : Protection contre les attaques XSS

1. Utilisez l'un de vos formulaire (ajout d'un `Twok`) pour tester un exploit
   de faille XSS (écrivez le code en JS). Que constatez-vous ?
   - Indice : Utilisez la balise `<script>` et la fonction `alert` en Javascript.
2. Modifiez le template Twig et ajoutez le filtre `raw` lorsque vous affichez
   la variable dans laquelle vous stockez votre exploit XSS (ex : `{{
   commentaire|raw }}`). Retestez l'attaque, que constatez-vous ?
3. Utilisez le composant `html-sanitizer` de Symfony pour permettre d'afficher
   du code (ex : un commentaire en rouge) mais sans permettre les failles XSS.
   Créez un formulaire simple pour tester les vulnérabilités XSS ou modifiez un
   formulaire existant.

## Partie 2 : Prévention des attaques CSRF

1. Vérifiez si la protection contre les CSRF est activée dans vos formulaires.
   Comment avez-vous fait ? Si elle est activée, désactivez-la.
2. Testez un exploit d'attaque CSRF sur l'un de vos formulaires.
   - Indice : Implémentez un formulaire dans une page HTML externe au projet,
     qui fait une requête POST vers votre site cite de l'attaque. Utilisez les
     fonction Javascript `getElementById` et `submit` pour forcer le browser à
     envoyer la requête sans le consentement de l'utilisateur. Si vous êtes
     machiavélique, trouvez une façon de ne pas afficher le formulaire sur la
     page.
3. Activez la protection CSRF dans les formulaires. Que constatez-vous ?
   Retestez votre attaque.
4. Utilisez la commande `curl` pour envoyer une requête POST sur votre
   formulaire avec et sans le token CSRF, que constatez-vous ?

## Partie 3 : Inscription sécurisée des utilisateurs

1. Générez une entité `User` qui sera identifié avec son email et qui aura un mot de passe, avec la commande :
   ```bash
   symfony console make:user
   ```
2. Générez un formulaire de login et logout pour l'entité `User` avec la commande suivante :
   ```bash
   symfony console make:security:form-login
   ```
3. Générez un formulaire d'inscription pour votre entité `User` avec la commande suivante :
   ```bash
   symfony console make:registration-form
   ```

   N'envoyez pas de mail de confirmation.

4. Utilisez des contraintes sur votre entité `User` pour vous assurer que :
   - Le mot de passe est fort : [https://symfony.com/doc/current/reference/constraints/PasswordStrength.html](https://symfony.com/doc/current/reference/constraints/PasswordStrength.html)
   - Le mot de passe est plus long que 8 charactères (contrainte sur la longueur)
   
   Testez votre formulaire pour valider que ces contraintes sont bien implémentées.

5. Vers quelle route votre site redirige l'utilisateur losqu'il se connecte et se déconnecte ?

## Partie 4 : Autorisation des utilisateurs avec des rôles

1. Notez que l'entité `User` a une propriété `role` qui contient le rôle de
   l'utilisateur (administrateur, utilisteur, etc). Quelle est la valeur par
   défaut ?

2. Nous allons créer un utilisateur normal et un administrateur pour tester nos
   permissions. Exécutez la commande suivante et créez le CRUD de l'entité `User` :
   ```bash
   symfony console make:crud
   ```
   Modifiez le fichier `src/Form/UserType.php` crée par la commande précédente et remplacez `->add('roles')` par
   ```php
   ->add('roles', ChoiceType::class, [
        'choices'  => [
            'ROLE_ADMIN' => 'ROLE_ADMIN',
            'ROLE_USER' => 'ROLE_USER',
        ], 'multiple' => true,
    ])
   ```

3. Utilisez le formulaire d'inscription pour inscrire au moins deux
   utilisateurs et utilisez le formulaire de modification nouvellement crée
   pour modifier le rôle d'un utilisateur en administrateur.


4. Restreignez l'accès aux routes en fonction des rôles des utilisateurs dans
   votre configuration de sécurité à l'aide du fichier
   `confi/packages/security.yaml` puis dans les fichiers des controlleurs (avec
   la primitive `IsGranted`) afin de restreindre les URL commençant par `/user`
   aux seuls administrateurs (le CRUD de modification des utilisateurs).

5. Essayer d'acceder aux URL `/user` et au reste de votre site sans être
   authentifié, en étant authentifié en tant qu'utilisateur et enfin en tant
   qu'administrateur afin de valider que votre configuration est correcte.
