Architecture(s) et
application(s) Web

CSC4101 - Sécurité, gestion des erreurs

13/11/2023

Plan de la séquence

Plan :

  1. Sécurité
  2. Gestion des erreurs
  3. Bugs, Qualité

La sécuritay c’est un métiay

hacker-dangereux.jpg

Pas le mien :-/

Objectifs

  • Éviter que les données ne soient corrompues
  • Garantir le bon fonctionnement du service
  • Garantir que les permissions accordées aux utilisateurs soient respectées

Danger: toute entrée de donnée

Exemple d’attaques

Injection SQL

  • Objectif : garantir que les requêtes SQL sont sans effet de bord
  • Nettoyer les données servant à constituer ces requêtes SQL

Cf. http://php.net/manual/fr/security.database.sql-injection.php

  • code PHP

    <?php
    
      $id = $_GET['id'];
      $sql = "SELECT username 
          FROM users
          WHERE id = $id";
    ...
    
  • requête envoyée à :

    http://localhost/?id=-1%20UNION%20SELECT%20password%20FROM%20users%20where%20id=1
    
  • argument de la requête GET :

    id : -1 UNION SELECT password FROM users where id=1
    

Exploits of a Mom (xkcd)

Cross Site Request Forgery (CSRF)

Induire l’exécution de transition dans le graphe d’états de l’application en jouant des requêtes à l’insu de l’utilisateur.

https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)

how_csrf_work.jpg

Source : https://www.wallarm.com/what/what-is-cross-site-request-forgery

Exemple de transaction sur site banque : virement de 100 euros à destination d’olivier :

POST http://bank.com/transfer.do HTTP/1.1

acct=olivier&amount=100

Objectif : faire exécuter ce formulaire à l’insu de l’utilisateur :

<form action="http://bank.com/transfer.do" method="POST">
  <input type="hidden" name="acct" value="philippe"/>
  <input type="hidden" name="amount" value="100000"/>
  <input type="submit" value="View my pictures"/>
</form>

Cross-site scripting (XSS)

Cross-site_scripting_attack_sequence_diagram_-_en.png

Source : Michel Bakni, CC BY-SA 4.0, via Wikimedia Commons

  • Donne accès aux données de l’application à un script tiers
  • cookies
  • jetons session

https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)

  • Exemple de page :

    <?php
    
      echo '<html>';
      // ...
      echo $_POST["name"];
    
  • Requête POST : injection de name qui vaut

    name=%3Cscript%3Ealert%2842%29;%3C/script%3E
    
  • Résultat :

    <script>alert(42);</script>
    

Tout dépend où se trouve le echo

Solution possible :

<?php

   echo '<html>';
   // ...
   echo htmlentities($_POST["name"]);

Résultat :

<html>
   ...
   &lt;script&gt;alert(42);&lt;/script&gt;

Normalement, c’est plus sûr…

Avantage du framework

Le framework permet de gérer automatiquement certaines précautions

Sanitization

  • Objectif : ne pas transmettre au Modèle des données avec des caractères indésirés
  • Supprime de manière automatique les caractères indésirés,
  • Champs des formulaires associés à un type de donnée pour restreindre les plages de valeur

Doctrine

On ne manipule pas SQL directement.

Gabarits

On ne manipule pas HTML directement

Sécurité des formulaires

Protection CSRF

Objectif : éviter d’arriver sur la soumission d’un formulaire directement, contrôler les transitions dans le graphe HATEOS

csrf-token-synchronizer.png

Figure 1 : Identifying Legitimate Requests with an CSRF Token

Source : https://reflectoring.io/complete-guide-to-csrf/

  • Contrôle que la gestion de la soumission d’un formulaire suit immédiatement l’affichage du formulaire
  • Paramètre caché généré de manière automatique (_token en Symfony)
  • Associé à une mémorisation du paramètre côté serveur (dans la session)

Construction du formulaire :

  1. stockage dans la session

    Session Attributes
    
    _csrf/post : "RfofubWU_auc33Mef-EdbvVlHOBh5J1561Z9rJ_FJ5I"
    
  2. génération du formulaire envoyé au client

    <form>
      ...
      <input type="hidden" id="post__token"
             name="post[_token]"
             value="RfofubWU_auc33Mef-EdbvVlHOBh5J1561Z9rJ_FJ5I" />
    </form>
    

Réception de la requête POST :

  • données du POST

    [▼
      "title" => "Lorem Ipsum"
      "summary" => ""
      "content" => "Lorem Ipsum"
      "publishedAt" => "2017-11-26T20:07:34+01:00"
      "tags" => ""
      "_token" => "RfofubWU_auc33Mef-EdbvVlHOBh5J1561Z9rJ_FJ5I"
    ]
    
  • code du contrôleur (dans isValid()) :

    if ($this->isCsrfTokenValid('token_id', $submittedToken)) {
            // ... 
    }
    

Inconvénient du framework

Sécurité des dépendances ?

S’abonner à des listes de notification de vulnérabilités, pour être notifié des alertes (CVE).

Sécurité des utilisateurs

  • Protéger les données des usagers :
    • argent
    • infos personnelles (RGPD)
    • vie privée
    • réputation
  • Lutter contre surveillance
    • chiffrement TLS (HTTPS)
    • accessibilité via TOR (domaine en .onion)

Contrôle d’accès

déjà vu

HTTPS everywhere

Sécurité des applis Web

Approfondir :

</securité>

Plan de la séquence

  1. Sécurité
  2. Gestion des erreurs
  3. Bugs, Qualité

Code de réponse

Strip-Response-code-650-final.jpg

Figure 2 : HTTP Headers FTW (CommitStrip)

HTTP Headers FTW par CommitStrip

Exceptions

throw new OutOfBoundsException("not good");

try {
    ...
} catch (RequestException $e) {
    ...
}

Environnement de dév

exceptions-in-dev-environment.png

Environnement de prod ?

errors-in-prod-environment.png

Pages d’affichage des erreurs dans les gabarits

Cf. How to Customize Error Pages.

Déployer

Checklists : https://symfony.com/doc/current/deployment.html

</erreurs>

Plan de la séquence

  1. Sécurité
  2. Gestion des erreurs
  3. Bugs, Qualité

Éviter les bugs

  • Coder
  • Tester

PHPUnit

Tests manuels ?

Vraiment ?

Tests unitaires

  • Tests des méthodes des objets du modèle, en dehors du contexte Web.
  • PHPUnit (très similaire à JUnit)

Tests « système »

Tester de bout en bout, systématiquement :

  1. Fabriquer une « requête » semblable à celle entrant depuis un client HTTP : accès à une route avec ses arguments
  2. Traiter
  3. Vérifier la réponse :
    • code de retour HTTP
    • présence de données dans le contenu (HTML)

Cf. https://symfony.com/doc/current/testing.html

public function testPageIsSuccessful($url)
{
        $client = self::createClient();
        $client->request('GET', $url);
        $this->assertTrue($client->getResponse()->isSuccessful());
}

</tests>

Take Away

  • sécurité de l’application :
    • données entrées ou fournies
  • sécurité des utilisateurs
  • qualité du code
  • le framework fait les choses « bien », et c’est tant mieux !
  • ne plus programmer en PHP « basique » comme autrefois

Postface

Crédits illustrations et vidéos

Copyright

  • Document propriété de ses auteurs et de Télécom SudParis (sauf exceptions explicitement mentionnées).
  • Réservé à l’utilisation pour la formation initiale à Télécom SudParis.