Plan :
Pas le mien :-/
Danger: toute entrée de donnée
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
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)
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>
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>
   ...
   <script>alert(42);</script>
Normalement, c’est plus sûr…
Le framework permet de gérer automatiquement certaines précautions
On ne manipule pas SQL directement.
On ne manipule pas HTML directement
Protection CSRF
Objectif : éviter d’arriver sur la soumission d’un formulaire directement, contrôler les transitions dans le graphe HATEOS
_token en Symfony)Construction du formulaire :
stockage dans la session
Session Attributes _csrf/post : "RfofubWU_auc33Mef-EdbvVlHOBh5J1561Z9rJ_FJ5I"
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)) {
        // ... 
}
Sécurité des dépendances ?
S’abonner à des listes de notification de vulnérabilités, pour être notifié des alertes (CVE).
.onion)déjà vu
Approfondir :
HTTP Headers FTW par CommitStrip
throw new OutOfBoundsException("not good");
try {
    ...
} catch (RequestException $e) {
    ...
}
Checklists : https://symfony.com/doc/current/deployment.html
PHPUnit
Vraiment ?
Tester de bout en bout, systématiquement :
public function testPageIsSuccessful($url)
{
          $client = self::createClient();
          $client->request('GET', $url);
          $this->assertTrue($client->getResponse()->isSuccessful());
}