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 |
À faire aussi pour la table reponse
Répétez exactement les mêmes étapes pour la table
reponse.
Il est important de sécuriser aussi la table reponse.
Cela permettra de :
- Lire les réponses dans l’application
- Empêcher toute modification accidentelle de la base
N’oubliez pas d’activer RLS sur la table reponse avant de créer les politiques, puis de répétez exactement les mêmes étapes pour la table reponse.
Pour gagner du temps, vous pouvez dupliquer les politiques créées pour la table question et les adapter à la table reponse.
Comment dupliquer une politique RLS ?
L’interface Supabase ne propose pas actuellement de bouton "Duplicate Policy".
Mais vous pouvez exporter le SQL, le modifier, puis l’exécuter pour créer les mêmes règles sur une autre table.
1. Exporter les politiques existantes en SQL
- Dans Supabase, allez dans l’onglet Table Editor
- Sélectionnez la table
question - Cliquez sur RLS Policies
- Pour chaque politique, cliquez sur les trois points (…) à droite
- Cliquez sur "Edit Policy"
- Une fenêtre affiche le code SQL de cette politique. Copiez ce code.
2. Modifier le SQL pour la table reponse
Prenez chaque politique copiée (par exemple celle pour autoriser la lecture) :
alter policy "Enable read access for all users"
on "public"."question"
to public
using (
true
);
et remplacez simplement :
alterparcreatequestionparreponse
Votre nouveau code SQL devient :
✅ Lecture autorisée à tous
create policy "Enable read access for all users"
on "public"."reponse"
to public
using (
true
);
Faites de même pour les autres politiques :
❌ Interdire INSERT
create policy "Deny insert for all users"
on "public"."reponse"
to public
with check (
false
);
❌ Interdire UPDATE
create policy "Deny update for all users"
on "public"."reponse"
to public
using (
false
) with check (
false
);
❌ Interdire DELETE
create policy "Deny delete for all users"
on "public"."reponse"
to public
using (
false
);
3. Exécuter le SQL dans la console Supabase
-
Dans Supabase, ouvrez l’onglet SQL Editor
-
Collez les 4 blocs SQL modifiés :
create policy "Enable read access for all users"
on "public"."reponse"
to public
using (
true
);
create policy "Deny insert for all users"
on "public"."reponse"
to public
with check (
false
);
create policy "Deny update for all users"
on "public"."reponse"
to public
using (
false
) with check (
false
);
create policy "Deny delete for all users"
on "public"."reponse"
to public
using (
false
);
-
Cliquez sur "Run"
-
Il ne reste plus qu'à activer RLS sur la table
reponse:
-
Dans le menu latéral gauche, cliquez sur Table Editor
-
Cliquez sur la table
reponse -
Cliquez sur le bouton
RLS disabled
-
Cliquez sur le bouton Enable RLS for this table

-
Cliquez sur le bouton Enable RLS

Vous avez maintenant les mêmes règles RLS sur la table reponse !

Vérification
-
Lancez votre projet Next.js
-
Vérifiez que les questions s’affichent toujours dans l’interface

- La base est sécurisée pour une utilisation publique
- Vous avez activé RLS sur les tables
questionetreponse - Vous avez autorisé la lecture publique
- Vous avez interdit toute autre action
- Votre base de données est maintenant sécurisée pour un usage public