# TP 5 : Sécurité des bases de données (12h) Pour ce TP, nous allons utiliser Docker. Vous pouvez l'installer sur votre machine ou dans une VM quelconque. Ce TP peut être réalisé dans la VM MI-LXC disponible [ici](https://flesueur.irisa.fr/mi-lxc/images/milxc-debian-amd64-1.4.1.ova) (identique à la première période). Avant de lancer la VM, il peut être nécessaire de diminuer la RAM allouée. Par défaut, la VM a 3GO : si vous avez 4GO sur votre machine physique, il vaut mieux diminuer à 2GO, voire 1.5GO pour la VM (la VM devrait fonctionner de manière correcte toujours). Décrivez vos manipulations et expérimentations dans un compte-rendu *individuel* qui devra être déposé sur Moodle à la fin des 12 heures. Quelques commandes utiles ========================= Dans la console psql : * \l lister les bases * \dt lister les tables * \du (\du+) lister les rôles (utilisateurs/groupes) * \z lister les permissions * TABLE clients; afficher la table clients * \c database; ouvrir la base database * La doc de référence : [doc](https://www.postgresql.org/docs/current/index.html) Démarrage (30 minutes) ========= Ici, on va démarrer une base PostgreSQL et faire de premières manipulations. Pour créer et démarrer un docker postgresql : `docker run --name mypostgres -e POSTGRES_PASSWORD=foo -d postgres` Ensuite, pour se connecter à la console : `docker exec -it mypostgres psql -U postgres` La base est persistente si vous stoppez/redémarrez le docker (à confirmer), mais pas en cas de fausse manip. Prenez des notes au fur et à mesure ! > Décrivez comment vous avez installé votre environnement pour ce TP. Création d'une première base (2 heures) ============================ Il faut tout d'abord comprendre la notion de rôles (utilisateurs/groupes) et de bases. Rôles ----- La documentation est à lire [ici](https://www.postgresql.org/docs/current/user-manag.html) (jusque 22.2 seulement pour l'instant). Les groupes et les utilisateurs sont des rôles avec des attributs différents. La modification d'un rôle est expliquée [ici](https://www.postgresql.org/docs/current/sql-alterrole.html). > Créez un utilisateur ayant le droit de se connecter, avec un mot de passe. Puis utilisez ALTER pour changer son mot de passe. Base ---- Une base est un ensemble de tables (relations) qui appartient à un utilisateur. La création de base est documentée [ici](https://www.postgresql.org/docs/current/managing-databases.html) (ignorez les parties templates et tablespaces). > Créez une nouvelle base qui doit appartenir à l'utilisateur que vous avez créé. Puis supprimez-là, récréez-là et utilisez ALTER pour modifier (puis remettre) son propriétaire. Tables ------ Les tables sont les éléments des bases qui vont contenir les données qui seront requêtées. Pour créer une table, la [doc](https://www.postgresql.org/docs/current/ddl-basics.html). Il faut ensuite la remplir avec [INSERT/UPDATE/DELETE](https://www.postgresql.org/docs/current/dml.html) et la requêter avec [SELECT](https://www.postgresql.org/docs/current/queries.html). > Créez une table, insérez et modifiez quelques lignes et requêtez-là avec un WHERE simple. Nous avons maintenant le nécessaire pour explorer les fonctionnalités de sécurité. Disponibilité (30 minutes) ============= Expérimentez le dump et la restauration tel que décrit [ici](https://www.postgresql.org/docs/current/backup-dump.html) Pour vous connecter en shell sur le docker, `docker exec -it mypostgres bash` (où bash peut évidemment être remplacé par toute commande que vous vouliez taper dans le docker). > Présentez votre déroulé. Décrivez le contenu du dump. Contrôle d'accès (3 heures) ================ Pour la confidentialité et l'intégrité, nous allons voir la gestion des comptes et des droits. << PAUSE COURS AU TABLEAU >> (à défaut, ces [slides](https://flesueur.irisa.fr/accesscontrol_fle.pdf) : lecture générale pour comprendre les différents modèles de contrôle d'accès, savoir s'y repérer et s'en inspirer, et évidemment avec un focus particulier sur la partie RBAC) Gestion des comptes ------------------- Il est maintenant temps de lire la gestion de l'appartenance aux rôles [ici](https://www.postgresql.org/docs/current/role-membership.html). > Créez quelques utilisateurs, quelques groupes et affectez des utilisateurs aux groupes. Gestion des droits ------------------ PostgreSQL permet de régler les droits : * des tables : [ici](https://www.postgresql.org/docs/current/ddl-priv.html) * des lignes : [ici](https://www.postgresql.org/docs/current/ddl-rowsecurity.html) La gestion par tables permet la première approche à grain moyen, la gestion par lignes permet ensuite une granularité de contrôle beaucoup plus fine. Les droits sont affectés à des rôles afin de faire du RBAC. > Sur une table, permettez à un rôle de lire uniquement (SELECT) et à un autre d'écrire. > Sur des lignes, limitez la lecture à l'utilisateur nommé sur la ligne. Mise en œuvre (6 heures) ============= Bravo ! Vous voilà maintenant responsable de mettre une formidable application en production ! Cette application a été développée avec les dernières technologies à la mode par le stagiaire qui vient de partir (parce que c'était, avant vous, le seul technique de l'organisation). Cette application est disponible dans le sous-dossier [tp5-files](tp5-files/). Vous pouvez la lancer avec `docker-compose up -d` (en étant placé dans le sous-dossier contenant le docker-compose.yml) et y accéder depuis votre hôte aux URLs `http://localhost/admin/`, `http://localhost/clients/` et `http://localhost/helpdesk/`. Vous pouvez explorer son code (et son README.txt) dans le sous-dossier [webapp](tp5-files/webapp/). La base initiale est décrite dans [sqlinit.sql](tp5-files/sqlinit/sqlinit.sql), ce qui vous permet de connaître les authentifiants attendus. Pour vous connecter à la base (credentials www/foo) : * `docker exec -it postgres psql -U www clientsdb` * ou via un navigateur vers `http://localhost:81` (phppgadmin) Et là, c'est le drame. En regardant `clients/do_login.php`, vous prenez peur pour la mise en production. > Quel est le problème dans ce fichier ? Retrouvez-vous ce problème ailleurs ? Qu'aurait-il fallu faire à la place ? Exploitez-le ! Malheureusement, la recette a déjà eu lieu et vous n'avez plus la possibilité de faire des modifications au travers de toute l'application. Nous allons explorer 2 voies de défense en profondeur afin de limiter les impacts : * Séparation des accès à la BD en 3 utilisateurs distincts admin/helpdesk/client puis restriction des droits sur les tables * Séparation des accès à la BD en n utilisateurs distincts appartenant à l'un des 3 rôles puis application de Row-Level security Segmentation des accès en 3 utilisateurs ---------------------------------------- Raffinez l'authentification entre l'application et la BD afin de limiter les dégâts potentiels : * Créez 3 utilisateurs distincts admin/helpdesk/client au niveau de la BD, qui correspondront aux usages des 3 sous-dossiers de l'application * Attribuez leur les droits minimaux nécessaires à chacune des sections de l'application (droits de SELECT, INSERT et UPDATE sur la table clients) * Modifiez l'inclusion du `db.inc.php` pour que les fichiers PHP de chaque sous-dossier se connectent à la base avec les credentials adaptés > Déployez ce modèle et mettez à jour le code PHP en fonction. Vérifiez que certaines exploitations initiales ne fonctionnent plus. Synthétisez vos changements dans le compte-rendu. Segmentation des accès en n utilisateurs ---------------------------------------- Raffinez l'authentification entre l'application et la BD afin de limiter les dégâts potentiels : * Un utilisateur de l'application web = un utilisateur de la BD * L'authentification sera réalisée directement avec la BD (stockages des authentifiants dans la session PHP) * Des rôles (hiérarchiques) pour factoriser la gestion des droits * Une sécurité à grain fin au niveau des lignes de tables (Row security) > Proposez (sur papier) et faîtes valider un modèle RBAC adapté. Déployez ce modèle et mettez à jour le code PHP en fonction. Vérifiez que votre exploitation initiale ne fonctionne plus. Synthétisez vos changements dans le compte-rendu. > REMARQUE : En l'absence de row-level security (pas disponible avec MySQL/MariaDB par exemple), un résultat relativement similaire (mais plus complexe à maintenir) aurait pu être obtenu avec l'utilisation de vues. Bonus ===== Choisissez une base NoSQL, étudiez, expérimentez et présentez dans votre rapport sa gestion des droits.