Web/TP/TPSecurite/README.md

144 lines
5.3 KiB
Markdown
Raw Permalink Normal View History

2023-05-25 11:50:30 +02:00
# 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é)