From d8a54afed84016b8b916c6c249239fad66079cdb Mon Sep 17 00:00:00 2001 From: dartoisl Date: Thu, 25 May 2023 11:50:30 +0200 Subject: [PATCH] TP securite --- TPSecurite/README.md | 143 ++++++++++++++++++++++++++++++++ TPSecurite/article_list.php | 40 +++++++++ TPSecurite/article_view.php | 72 ++++++++++++++++ TPSecurite/comment_create.php | 50 +++++++++++ TPSecurite/csrf.html | 9 ++ TPSecurite/extra/db.sql | 136 ++++++++++++++++++++++++++++++ TPSecurite/lib/common.php | 9 ++ TPSecurite/templates/footer.php | 9 ++ TPSecurite/templates/header.php | 9 ++ TPSecurite/user_create.php | 48 +++++++++++ TPSecurite/user_login.php | 39 +++++++++ TPSecurite/web_security.txt | 60 ++++++++++++++ 12 files changed, 624 insertions(+) create mode 100755 TPSecurite/README.md create mode 100755 TPSecurite/article_list.php create mode 100755 TPSecurite/article_view.php create mode 100755 TPSecurite/comment_create.php create mode 100755 TPSecurite/csrf.html create mode 100755 TPSecurite/extra/db.sql create mode 100755 TPSecurite/lib/common.php create mode 100755 TPSecurite/templates/footer.php create mode 100755 TPSecurite/templates/header.php create mode 100755 TPSecurite/user_create.php create mode 100755 TPSecurite/user_login.php create mode 100755 TPSecurite/web_security.txt diff --git a/TPSecurite/README.md b/TPSecurite/README.md new file mode 100755 index 0000000..b52c7cc --- /dev/null +++ b/TPSecurite/README.md @@ -0,0 +1,143 @@ + +# 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. +
Aide + Regardez l'url ! +
+ +3. Sécurisez l'écriture du formulaire `comment_create.php` afin qu'on + ne puisse pas accéder à un commentaire d'un autre utilisateur. +
Aide + Dans la requête de modification d'un commentaire, ajoutez à la + clause WHERE la vérification du user. +
+ +4. Le client peut-il modifier le formulaire, en changeant par exemple + l'id du commentaire à modifier ? comment ? +
Aide + Il suffit d'écrire son propre formulaire, avec la possibilité de + saisir le champ id du commentaire ! +
+ +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. +
Aide +
+ générez un hash avec une clé secrète : + $hashCode = hash_hmac("sha256",$_REQUEST['id_comment'],"Ma clé"); + echo ''; + Au moment du traitement du formulaire, quand on reçoit le champ `id_comment`, on recalcule et compare le hash avec celui reçu. +
+
+ +##### XSS + +1. Ajoutez un commentaire qui masque tout ce qui suit son affichage + (uniquement de l'html svp !). Revenez à un fonctionnement normal. + +
Aide + Pensez à fermer des balises, et à en ouvrir une qui cachera tout le + reste au moyen d'une propriété css. +
+ +2. Ajoutez un commentaire qui modifie le titre `h1` de la page de + l'article. + +
Aide +
+ Le javascript permet de modifier le contenu HTML d'un élément : + document.querySelector("h1").innerHTML = "hey !!!!"; +
+
+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`. +
Aide +
+ javascript:alert(/XSS !/); +
+
+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 ...) +
Aide + 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 ... +
+ + +##### 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. + +
Aide + Regerdez la clause WHERE dans la requête d'update d'un + commentaire. +
+ +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é) diff --git a/TPSecurite/article_list.php b/TPSecurite/article_list.php new file mode 100755 index 0000000..8b9d9a9 --- /dev/null +++ b/TPSecurite/article_list.php @@ -0,0 +1,40 @@ + + + + + + +

Liste des articles

+ +Bonjour, " . $_SESSION['user']['name']. ".

"; +} +?> + + + + + + + diff --git a/TPSecurite/article_view.php b/TPSecurite/article_view.php new file mode 100755 index 0000000..c7a058e --- /dev/null +++ b/TPSecurite/article_view.php @@ -0,0 +1,72 @@ + + + + +

Article

+ +' + . '

'. $article['title'] .'

' + . '
' . $article['content'] . '
'; + +echo '
Commentaires
'; +if (empty($comments)) { + echo '

Aucun

'; +} else { + foreach ($comments as $comment) { + echo '
'; + echo "".$comment['title']."" + . (isset($_SESSION['user']['id']) && $comment['id_user'] == $_SESSION['user']['id'] ? + ' Modifier ce commentaire' : + '') + . '

' . $comment['content'] ."

" + . "

".$comment['login']."

"; + echo "
"; + } +} +echo ""; + +if (empty($_SESSION['user'])) { + echo '

Il faut être identifié pour poster un commentaire.

'; +} else { + if ($article['closed']) { + echo "

Article fermé, non modifiable.

"; + } else { + echo '

Ajouter un commentaire avec votre compte : ' . $_SESSION['user']['name'] + .'

'; + } +} +?> + +

Retour à la liste des articles

+ + + + + diff --git a/TPSecurite/comment_create.php b/TPSecurite/comment_create.php new file mode 100755 index 0000000..9d4ebce --- /dev/null +++ b/TPSecurite/comment_create.php @@ -0,0 +1,50 @@ + + + + +

Ajouter/modifier un commentaire

+
+
+\n"; +} ?> + +
+
+ +
+
+ + + diff --git a/TPSecurite/csrf.html b/TPSecurite/csrf.html new file mode 100755 index 0000000..39aa733 --- /dev/null +++ b/TPSecurite/csrf.html @@ -0,0 +1,9 @@ + + + Sécurité PHP + + + + image + + diff --git a/TPSecurite/extra/db.sql b/TPSecurite/extra/db.sql new file mode 100755 index 0000000..fc77226 --- /dev/null +++ b/TPSecurite/extra/db.sql @@ -0,0 +1,136 @@ +-- phpMyAdmin SQL Dump +-- version 4.7.0 +-- https://www.phpmyadmin.net/ +-- +-- Host: localhost +-- Generation Time: May 29, 2017 at 06:15 AM +-- Server version: 10.1.22-MariaDB +-- PHP Version: 7.1.4 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +SET AUTOCOMMIT = 0; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- Database: `securite` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `article` +-- + +CREATE TABLE `article` ( + `id` int(11) NOT NULL, + `title` text COLLATE utf8mb4_unicode_ci, + `closed` decimal(10,0) DEFAULT NULL, + `content` text COLLATE utf8mb4_unicode_ci +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- +-- Dumping data for table `article` +-- + +INSERT INTO `article` (`id`, `title`, `closed`, `content`) VALUES +(1, 'Premier', '1', 'Premier message, sans commentaire.'), +(2, 'Second', '0', 'Second message, avec des commentaires.'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `comment` +-- + +CREATE TABLE `comment` ( + `id` int(11) NOT NULL, + `id_article` decimal(10,0) DEFAULT NULL, + `title` text COLLATE utf8mb4_unicode_ci, + `id_user` decimal(10,0) DEFAULT NULL, + `content` text COLLATE utf8mb4_unicode_ci +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- +-- Dumping data for table `comment` +-- + +INSERT INTO `comment` (`id`, `id_article`, `title`, `id_user`, `content`) VALUES +(1, '2', 'Super', '2', 'Article très intéressant !'), +(2, '2', 'Un commentaire', '1', 'Pour tester !'), +(3, '2', 'Un deuxième commentaire', '1', 'ça casse pas trois pattes à un canard !'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `user` +-- + +CREATE TABLE `user` ( + `id` int(11) NOT NULL, + `login` varchar(60) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `name` varchar(60) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `password` text COLLATE utf8mb4_unicode_ci, + `url` text COLLATE utf8mb4_unicode_ci +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- +-- Dumping data for table `user` +-- + +INSERT INTO `user` (`id`, `login`, `name`, `password`, `url`) VALUES +(1, 'francois', 'François', 'mdp', 'http://fr.php.net'), +(2, 'denis', 'Denis', 'moi', 'http://lemonde.fr'); + +-- +-- Indexes for dumped tables +-- + +-- +-- Indexes for table `article` +-- +ALTER TABLE `article` + ADD PRIMARY KEY (`id`); + +-- +-- Indexes for table `comment` +-- +ALTER TABLE `comment` + ADD PRIMARY KEY (`id`); + +-- +-- Indexes for table `user` +-- +ALTER TABLE `user` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `login` (`login`); + +-- +-- AUTO_INCREMENT for dumped tables +-- + +-- +-- AUTO_INCREMENT for table `article` +-- +ALTER TABLE `article` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3; +-- +-- AUTO_INCREMENT for table `comment` +-- +ALTER TABLE `comment` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=23; +-- +-- AUTO_INCREMENT for table `user` +-- +ALTER TABLE `user` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;COMMIT; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/TPSecurite/lib/common.php b/TPSecurite/lib/common.php new file mode 100755 index 0000000..84cd4e4 --- /dev/null +++ b/TPSecurite/lib/common.php @@ -0,0 +1,9 @@ + +

+ +

+

+ +

+ + diff --git a/TPSecurite/templates/header.php b/TPSecurite/templates/header.php new file mode 100755 index 0000000..4a2f280 --- /dev/null +++ b/TPSecurite/templates/header.php @@ -0,0 +1,9 @@ + + + + + Sécurité PHP + + + + diff --git a/TPSecurite/user_create.php b/TPSecurite/user_create.php new file mode 100755 index 0000000..6ed80c2 --- /dev/null +++ b/TPSecurite/user_create.php @@ -0,0 +1,48 @@ + + + + + + +

Création de compte

+
+
+
+ +
+
+ +
+
+ +
+
+ +

Retour à la liste des articles

+ + + + + diff --git a/TPSecurite/user_login.php b/TPSecurite/user_login.php new file mode 100755 index 0000000..6bc7e66 --- /dev/null +++ b/TPSecurite/user_login.php @@ -0,0 +1,39 @@ + + + + + +

Authentification et injection SQL

+
+
+
+
+
+ +
+
+ + + diff --git a/TPSecurite/web_security.txt b/TPSecurite/web_security.txt new file mode 100755 index 0000000..550a8d6 --- /dev/null +++ b/TPSecurite/web_security.txt @@ -0,0 +1,60 @@ +[ Une liste de ressources partagée par Théo Debauvais ] + +XSS: + explication: + https://owasp.org/www-project-top-ten/OWASP_Top_Ten_2017/Top_10-2017_A7-Cross-Site_Scripting_(XSS) + https://www.acunetix.com/websitesecurity/xss/ + défense: + + site pour s'entrainer (que des DOM-XSS et client-side XSS): https://xss.pwnfunction.com/ + +Injection SQL: +explication: + explication: + https://owasp.org/www-project-top-ten/OWASP_Top_Ten_2017/Top_10-2017_A1-Injection + https://owasp.org/www-community/attacks/SQL_Injection + https://www.w3schools.com/sql/sql_injection.asp + défense: + https://www.php.net/manual/en/mysqli.real-escape-string.php ou une fonction similaire en fonction du language que vous utilisez + Preparez vos requests, ou echappez les entrée comme ci-dessus + Programme pour tester automatiquement : http://sqlmap.org/ + +Local File Inclusion (LFI) / Remote File Inclusion (RFI): + https://en.wikipedia.org/wiki/File_inclusion_vulnerability + +CSRF: + explication: + https://portswigger.net/web-security/csrf + https://owasp.org/www-community/attacks/csrf + défense: + https://thisinterestsme.com/php-csrf-protection/ , surtout le principe utilisé + +OS injection: + explication: + https://portswigger.net/web-security/os-command-injection + https://owasp.org/www-community/attacks/Command_Injection + défense: + + +Pourquoi il ne faut pas essayer de cacher des fichiers sur un serveur http: +https://github.com/OJ/gobuster +https://tools.kali.org/web-applications/dirbuster +https://tools.kali.org/web-applications/dirb + +Liste de vulnérabilitées (PortSwigger est une référence avec OWASP, ils développent https://tools.kali.org/web-applications/burpsuite, download=https://portswigger.net/burp): +https://portswigger.net/web-security/all-materials + +Liste des failles web les plus connues (référence): +https://owasp.org/www-project-top-ten/ + +Applications vulnérables pour s'entrainer: +http://www.dvwa.co.uk/ +http://itsecgames.com/ + +Site connus pour apprendre et s'entrainer (très axé sur le pentest, moins sur la défense): +https://www.root-me.org/ +https://www.hackthebox.eu/ +https://tryhackme.com/ + +Lectures de Stanford sur la sécurité web (très récent: commence en septembre 2019; très bon et explique plein d'autres failles et sujets sur la sécurité web): +https://www.youtube.com/watch?v=5JJrJGZ_LjM&list=PLMF2PpA06Sb26oYT-dfNOt3Y4wwoLAho0