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).
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).
<<PAUSECOURSAUTABLEAU>> (à 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)
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.
> 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.