Sécurité RLS
Comment les mécanismes RLS fonctionnent et pourquoi ils sont indispensables dans la cybersécurité aujourd’hui ?

Notions théoriques
Qu’est-ce que RLS ?
Row-Level Security (RLS) est un mécanisme de sécurité (de certaines bases de données relationnelles) qui permet de contrôler l'accès aux lignes d'une table en fonction de l’utilisateur connecté.
Cela permet de dire par exemple :
"Un joueur connecté peut voir ses scores, mais pas ceux des autres."
Ou encore :
"Un utilisateur non connecté peut voir les questions, mais ne peut pas les modifier."
Pourquoi utiliser RLS ?
Pourquoi les RLS de PostgreSQL/Supabase sont essentielles pour la cybersécurité ?
1. Garantir que chacun n’accède qu’aux données qui le concernent. Avec les RLS, la base de données contrôle elle-même quelles lignes un utilisateur peut consulter ou modifier. Cela évite qu’un utilisateur, même légitime, voie des informations qui ne lui sont pas destinées.
2. Assurer une protection fiable, même en cas d’erreur applicative. La sécurité n’est pas seulement gérée dans le code : elle est intégrée au cœur de la base. Ainsi, même si l’application comporte un bug ou une faille, les données restent protégées par des règles robustes.
3. Se préparer aux bonnes pratiques du monde professionnel. Les RLS sont utilisées dans de nombreux environnements pour prévenir les fuites de données et respecter les exigences de sécurité. Les comprendre et savoir les mettre en place, c’est déjà adopter une posture professionnelle en cybersécurité.
Ne pas utiliser les RLS, c’est prendre le risque que des utilisateurs malveillants ou même accidentels accèdent à des données sensibles ou modifient des informations critiques.
Par défaut, dans PostgreSQL/Supabase :
- Sans RLS, toutes les données sont accessibles (lecture, écriture, suppression)
- Même un utilisateur non connecté peut modifier les données (dangereux !)
Il est donc essentiel de mettre en place des règles de sécurité avec les RLS.
Comment fonctionne RLS ?
- Vous activez RLS sur une table
- Vous écrivez des règles (policies) pour définir :
- Qui peut lire
- Qui peut écrire
- Qui peut modifier
- Qui peut supprimer
Ces règles sont écrites en SQL, mais Supabase vous propose une interface graphique simple pour les créer.
Exemple de règle RLS
Autoriser à lire toutes les questions, même sans être connecté :
CREATE POLICY "Lecture publique"
ON question
FOR SELECT
USING (true);
Empêcher toute modification :
CREATE POLICY "Pas d'écriture publique"
ON question
FOR INSERT, UPDATE, DELETE
USING (false);
Tables concernées dans notre projet
Nous allons appliquer les RLS sur les tables suivantes :
| Table | Rôle des RLS |
|---|---|
question | Lecture autorisée à tous, écriture interdite |
reponse | Lecture autorisée à tous, écriture interdite |
D’autres tables comme
joueurouscoreauront des règles différentes (nous verrons ça plus tard).
Exemple pratique
Imaginons que vous avez une table question avec les colonnes suivantes :
idtexteimage_urlexplication
Sans RLS, n’importe qui peut :
- Lire les questions
- Modifier ou supprimer les questions
- Ajouter de nouvelles questions
Avec RLS activé et bien configuré, vous pouvez :
- Autoriser tout le monde à lire les questions
- Interdire tout le monde à modifier les questions
Test de mémorisation / compréhension
TP pour réfléchir et résoudre des problèmes
Objectif
Configurer les règles RLS sur les tables question et reponse pour :
- Autoriser la lecture à tous (même sans être connecté)
- Interdire toute modification (insertion, mise à jour, suppression)
Étapes à suivre
1. Activer RLS
-
Connectez-vous à votre projet Supabase
-
Dans le menu latéral gauche, cliquez sur Table Editor

-
Cliquez sur la table
question
-
Cliquez sur le bouton
RLS disabled
-
Cliquez sur le bouton Enable RLS for this table

-
Cliquez sur le bouton Enable RLS

Le bouton Enable RLS for this table devient Add RLS policy une fois activé.
-
Cliquez sur le bouton Add RLS policy

2. Permettre à tous de lire
Ajouter une politique de lecture pour permettre à tous les utilisateurs de lire les questions.
-
Après avoir cliquer sur le bouton Add RLS policy, vous arrivez sur cette interface :

-
Cliquez sur Create Policy

-
Dans la section Policy Name, choisissez un nom pour la politique, par exemple
Enable read access for all users
-
Dans la section Policy Behavior, choisissez Permissive

-
Dans la section Policy Command, choisissez SELECT

-
Dans la section Target Roles, choisissez Defaults to all (public) roles if not selected

-
A la place de
-- Provide a SQL expression for the using statement, saisisseztrueattentionLe fait de mettre
truedans la partieusingde la RLS va toujours autoriserSELECTpourpublic, c'est à dire que tout le monde pourra lire toutes les questions. -
Cliquez sur le bouton Save Policy

La règle RLS est maintenant créée pour autoriser la lecture des questions à tous les utilisateurs.

Maintenant nous allons bloquer les autres actions : INSERT, UPDATE, DELETE.
Il vous suffit d'ajouter des politiques RLS pour interdire l’ajout, la modification et la suppression de questions, même pour les utilisateurs connectés.
Nous allons créer 3 politiques distinctes :
- Une pour bloquer les INSERT
- Une pour bloquer les UPDATE
- Une pour bloquer les DELETE
3. Interdire d'insérer
C'est à dire interdire à tous d'utiliser INSERT sur la table
question.
-
Dans Supabase, allez dans l’onglet Table Editor
-
Sélectionnez la table
question -
Cliquez sur l’onglet Policies
-
Cliquez sur Create Policy

-
Dans Policy Name, entrez un nom clair comme :
Deny insert for all users
-
Dans Policy Behavior, choisissez Restrictive
(Cela signifie que la politique est bloquante)
-
Dans Policy Command, sélectionnez INSERT

-
Dans Target Roles, laissez Defaults to all (public) roles if not selected

-
Et enfin, dans la section Use options above to edit
On souhaite interdire complètement l’action, il suffit d'écrire
falsedans la clauseWITH CHECK:create policy "Deny insert for all users"
on "public"."question"
as RESTRICTIVE
for INSERT
to public
with check (
false
);
Explications sur le code SQL
create policy "Deny insert for all users": Crée une politique nommée "Deny insert for all users".on "public"."question": Applique cette politique à la tablequestiondans le schémapublic.as RESTRICTIVE: Indique que cette politique est de type restrictive (bloquante).for INSERT: La politique s'applique aux opérations d'insertion (INSERT).to public: La politique s'applique à tous les rôles publics (tous les utilisateurs).with check ( false ): Définit la condition pour l'insertion. Ici,falsesignifie qu'aucune insertion n'est autorisée.
-
Cliquez sur Save Policy
astuceAvec la règle (policy en anglais) que vous venez de mettre en place, personne ne peut insérer de question.
4. Interdire de modifier
C'est à dire interdire à tous d'utiliser UPDATE sur la table
question.
-
Dans Supabase, allez dans l’onglet Table Editor
-
Sélectionnez la table
question -
Cliquez sur l’onglet Policies
-
Cliquez sur Create Policy

-
Dans Policy Name, entrez un nom clair comme :
Deny update for all users
-
Dans Policy Behavior, choisissez Restrictive
(Cela signifie que la politique est bloquante)
-
Dans Policy Command, sélectionnez UPDATE

-
Dans Target Roles, laissez Defaults to all (public) roles if not selected

-
Et enfin, dans la section Use options above to edit
On souhaite interdire complètement l’action, il suffit d’écrire
falsedans la clauseUSINGetfalsedans la clauseWITH CHECK:create policy "Deny update for all users"
on "public"."question"
as RESTRICTIVE
for UPDATE
to public
using (
false
)
with check (
false
);

Explications sur le code SQL
create policy "Deny update for all users": Crée une politique nommée "Deny update for all users".on "public"."question": Applique cette politique à la tablequestiondans le schémapublic.as RESTRICTIVE: Indique que cette politique est de type restrictive (bloquante).for UPDATE: La politique s'applique aux opérations de mise à jour (UPDATE).to public: La politique s'applique à tous les rôles publics (tous les utilisateurs).using ( false ): Définit la condition pour autoriser la mise à jour. Ici,falsesignifie que personne n’est autorisé à modifier une ligne.
- Cliquez sur Save Policy

Avec cette règle (policy) en place, aucun utilisateur (même connecté) ne peut modifier les questions.
5. Interdire de supprimer
C'est à dire interdire à tous d'utiliser DELETE sur la table
question.
-
Dans Supabase, allez dans l’onglet Table Editor
-
Sélectionnez la table
question -
Cliquez sur l’onglet Policies
-
Cliquez sur Create Policy

-
Dans Policy Name, entrez un nom clair comme :
Deny delete for all users
-
Dans Policy Behavior, choisissez Restrictive
(Cela signifie que la politique est bloquante)
-
Dans Policy Command, sélectionnez DELETE

-
Dans Target Roles, laissez Defaults to all (public) roles if not selected

-
Et enfin, dans la section Use options above to edit
On souhaite interdire complètement l’action, il suffit d’écrire
falsedans la clauseUSING:create policy "Deny delete for all users"
on "public"."question"
as RESTRICTIVE
for DELETE
to public
using (
false
);

Explications sur le code SQL
create policy "Deny delete for all users": Crée une politique nommée "Deny delete for all users".on "public"."question": Applique cette politique à la tablequestiondans le schémapublic.as RESTRICTIVE: Indique que cette politique est de type restrictive (bloquante).for DELETE: La politique s’applique aux opérations de suppression (DELETE).to public: La politique s’applique à tous les rôles publics (tous les utilisateurs).using ( false ): Condition d’exécution de l’opération. Ici,falsesignifie que personne ne peut supprimer de ligne.
- Cliquez sur Save Policy

Avec cette règle (policy) en place, aucun utilisateur ne peut supprimer une question.
En résumé
Nous avons maintenant 4 RLS dans la table question :
| Nom de la politique | Action | Politique | Type | Condition |
|---|---|---|---|---|
| Enable read access for all users | SELECT | Permettre lecture | Permissive | true |
| Deny insert for all users | INSERT | Interdire insert | Restrictive | using: false with check: false |
| Deny update for all users | UPDATE | Interdire update | Restrictive | using: false |
| Deny delete for all users | DELETE | Interdire delete | Restrictive | using: false |