
# Introduction à la sécurité des applis web en PHP.


Le tp utilise une application de mini-blog. Le code PHP est
volontairement simplifié et suffisamment laxiste pour illustrer les
failles de sécurité abordées en cours.

Le site est à télécharger et déployer sur votre site local.
Il utilise un base de données sql. Vous pouvez directement
l'importer (répertoire `extra`). Les paramètres (à modifier) pour l'accès à la base
de données sont dans `lib/common.php`.

Avant de démarrer, consultez les pages existantes, créez un compte et
authentifiez-vous.

#### Formulaires et html 

##### Modification de contenu

1. Postez un commentaire sur un article.
2. Modifiez votre commentaire. Modifiez le commentaire d'un autre
   utilisateur.
   <details><summary>Aide</summary>
   Regardez l'url !
   </details>

3. Sécurisez l'écriture du formulaire `comment_create.php` afin qu'on
   ne puisse pas accéder à un commentaire d'un autre utilisateur.
   <details><summary>Aide</summary>
   Dans la requête de modification d'un commentaire, ajoutez à la
   clause WHERE la vérification du user.
   </details>

4. Le client peut-il modifier le formulaire, en changeant par exemple
   l'id du commentaire à modifier ? comment ?
   <details><summary>Aide</summary>
   Il suffit d'écrire son propre formulaire, avec la possibilité de
   saisir le champ id du commentaire !
   </details>

5. Pour se prémunir contre cela, on va, dans le formulaire, rajouter un
   code d'authentification (hash avec une clé secrète) du champ
   `id_comment` pour être sur que les données proviennent du formulaire
   de l'application. Utilisez la fonction
   [hash_mac](http://php.net/manual/fr/function.hash-hmac.php). Rajoutez, 
   dans le formulaire, un hash que vous pourrez comparé au hash re-calculé après l'envoie des données.
   <details><summary>Aide</summary>
   <div>
   générez un hash avec une clé secrète :
		$hashCode = hash_hmac("sha256",$_REQUEST['id_comment'],"Ma clé");
		echo '<input name="cle" type="hidden" value="'.$hashcode .'" >';
   Au moment du traitement du formulaire, quand on reçoit le champ `id_comment`, on recalcule et compare le hash avec celui reçu.
   </div>
   </details>

##### XSS

1.  Ajoutez un commentaire qui masque tout ce qui suit son affichage
    (uniquement de l'html svp !). Revenez à un fonctionnement normal.

	<details><summary>Aide</summary>
    Pensez à fermer des balises, et à en ouvrir une qui cachera tout le
    reste au moyen d'une propriété css.
	</details>

2.  Ajoutez un commentaire qui modifie le titre `h1` de la page de
    l'article.
	
	<details><summary>Aide</summary>
	<div>
    Le javascript permet de modifier le contenu HTML d'un élément :
		document.querySelector("h1").innerHTML = "hey !!!!";
	</div>
	</details>
3.  Empêchez la saisie de balises HTML (les supprimer) pour éviter les
    attaques ci-dessus. Est-ce suffisant ?

4.  Echappez (protéger) les textes affichés dans le html
    (htmlspecialchars).

5.  Créez un compte en donnant une url de façon à exploiter une faille
    XSS sur la page `article_view.php`.
	<details><summary>Aide</summary>
	<div>
		javascript:alert(/XSS !/);
	</div>
	</details>
6.  Proposez une url vers la page `user_login.php` qui affiche dans un
    popup les login/mots de passe saisies dans le formulaire (cela
    pourrait être plus dangereux, en les envoyant sur un serveur par
    exemple ...)
	<details><summary>Aide</summary>
    La valeur de la variable login est écrite dans le formulaire, dans
    l'attribut value du champ texte correspondant.
    Il donc tout à fait possible d'injecter du code javascript via un
    attribut html, par exemple onchange ...
	</details>   


##### CSRF

Les vunérabilités de type CSRF (Cross-Site Request Forgery) consiste à
forger de fausses requêtes à partir d'url authentifiées et à pousser le
client à exécuter des actions sans le savoir.

Le client authentifié exécute à son insu une requête (suppression par
exemple) par un formulaire dissimuler ou une balise image contrôlée par
du javascript.

1.  Se rendre sur la page `csrf.html` (soyez authentifié). Que s'est-il
    passé ?
2.  Passer les données en POST résoudra le problème précédent.
    Malheureusement, on pourra quand même créer une attaque avec du
    javascript. (vous verrez l'année prochaine qu'on peut faire une
    requête http à partir de javasscript.
3.  Résoudre le problème en utilisant un token unique dans le
    formulaire.

#### Injection SQL {#injection-sql .alert}

1.  Sur la page `user_login.php`, connectez-vous sans mot de passe,
    juste avec un login valide.
2.  connectez-vous sans mot de passe ni login.
3.  "Sécurisez" avec la méthode `quote` de PDO.
4.  Sur la page `comment_create.php`, malgré l'échappement SQL,
    prouvez que l'on peut toujours modifier les commentaires d'autrui.

	<details><summary>Aide</summary>
    Regerdez la clause WHERE dans la requête d'update d'un
    commentaire.
	</details>

5.  Utilisez le [filtrage](http://fr.php.net/manual/fr/book.filter.php)
    en entrée des données.
6.  Sécurisez la page `comment_create.php` avec des requêtes
    préparées.

#### Sessions 

1.  Utilisez une faille XSS pour afficher le contenu du cookie. Volez
    alors la session associée. (Il suffit d'écrire depuis un autre
    navigateur la valeur du cookie récupéré)
