Aller au contenu principal

Sécurité RLS

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

04_enable_rls_question.png

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é.

attention

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 ?

  1. Vous activez RLS sur une table
  2. 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 :

TableRôle des RLS
questionLecture autorisée à tous, écriture interdite
reponseLecture autorisée à tous, écriture interdite

D’autres tables comme joueur ou score auront des règles différentes (nous verrons ça plus tard).


Exemple pratique

Imaginons que vous avez une table question avec les colonnes suivantes :

  • id
  • texte
  • image_url
  • explication
Rappel

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


Que signifie RLS dans Supabase ?


Pourquoi activer RLS sur la table `question` ?


Que fait la condition `USING (true)` dans une politique RLS ?


Quelle action est concernée par une politique `FOR SELECT` ?


Si aucune politique RLS n’est définie, que se passe-t-il ?



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

    01_enable_rls_question.png

  • Cliquez sur la table question

    02_enable_rls_question.png

  • Cliquez sur le bouton RLS disabled

    02b_enable_rls_question.png

  • Cliquez sur le bouton Enable RLS for this table

    03_enable_rls_question.png

  • Cliquez sur le bouton Enable RLS

    04_enable_rls_question.png

Le bouton Enable RLS for this table devient Add RLS policy une fois activé.

  • Cliquez sur le bouton Add RLS policy

    05_enable_rls_question.png


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 :

    06_add_policy_question.png

  • Cliquez sur Create Policy

    06b_add_policy_question.png

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

    07_add_policy_question.png

  • Dans la section Policy Behavior, choisissez Permissive

    08_add_policy_question.png

  • Dans la section Policy Command, choisissez SELECT

    09_add_policy_question.png

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

    10_add_policy_question.png

  • A la place de -- Provide a SQL expression for the using statement, saisissez true

    attention

    Le fait de mettre true dans la partie using de la RLS va toujours autoriser SELECT pour public, c'est à dire que tout le monde pourra lire toutes les questions.

  • Cliquez sur le bouton Save Policy

    11_add_policy_question.png

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

12_question_policies.png

info

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.

  1. Dans Supabase, allez dans l’onglet Table Editor

  2. Sélectionnez la table question

  3. Cliquez sur l’onglet Policies

  4. Cliquez sur Create Policy

    13_question_policies.png

  5. Dans Policy Name, entrez un nom clair comme :
    Deny insert for all users

    14_question_policies.png

  6. Dans Policy Behavior, choisissez Restrictive
    (Cela signifie que la politique est bloquante)

    15_question_policies.png

  7. Dans Policy Command, sélectionnez INSERT

    16_question_policies.png

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

    17_question_policies.png

  9. Et enfin, dans la section Use options above to edit

    On souhaite interdire complètement l’action, il suffit d'écrire false dans la clause WITH CHECK :

    create policy "Deny insert for all users"
    on "public"."question"
    as RESTRICTIVE
    for INSERT
    to public
    with check (
    false
    );

    18_question_policies.png

    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 table question dans le schéma public.
    • 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, false signifie qu'aucune insertion n'est autorisée.
  10. Cliquez sur Save Policy

    19_question_policies.png

    astuce

    Avec 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.

  1. Dans Supabase, allez dans l’onglet Table Editor

  2. Sélectionnez la table question

  3. Cliquez sur l’onglet Policies


  1. Cliquez sur Create Policy

    20_question_policies.png


  1. Dans Policy Name, entrez un nom clair comme :
    Deny update for all users

    21_question_policies.png


  1. Dans Policy Behavior, choisissez Restrictive
    (Cela signifie que la politique est bloquante)

    22_question_policies.png


  1. Dans Policy Command, sélectionnez UPDATE

    23_question_policies.png


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

    24_question_policies.png


  1. Et enfin, dans la section Use options above to edit

    On souhaite interdire complètement l’action, il suffit d’écrire false dans la clause USING et false dans la clause WITH CHECK :

    create policy "Deny update for all users"
    on "public"."question"
    as RESTRICTIVE
    for UPDATE
    to public
    using (
    false
    )
    with check (
    false
    );

25_question_policies.png

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 table question dans le schéma public.
  • 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, false signifie que personne n’est autorisé à modifier une ligne.

  1. Cliquez sur Save Policy

26_question_policies.png

astuce

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.

  1. Dans Supabase, allez dans l’onglet Table Editor

  2. Sélectionnez la table question

  3. Cliquez sur l’onglet Policies


  1. Cliquez sur Create Policy

    27_question_policies.png


  1. Dans Policy Name, entrez un nom clair comme :
    Deny delete for all users

    28_question_policies.png


  1. Dans Policy Behavior, choisissez Restrictive
    (Cela signifie que la politique est bloquante)

    29_question_policies.png


  1. Dans Policy Command, sélectionnez DELETE

    30_question_policies.png


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

    31_question_policies.png


  1. Et enfin, dans la section Use options above to edit

    On souhaite interdire complètement l’action, il suffit d’écrire false dans la clause USING :

    create policy "Deny delete for all users"
    on "public"."question"
    as RESTRICTIVE
    for DELETE
    to public
    using (
    false
    );

32_question_policies.png

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 table question dans le schéma public.
  • 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, false signifie que personne ne peut supprimer de ligne.

  1. Cliquez sur Save Policy

33_question_policies.png

astuce

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 politiqueActionPolitiqueTypeCondition
Enable read access for all usersSELECTPermettre lecturePermissivetrue
Deny insert for all usersINSERTInterdire insertRestrictiveusing: false with check: false
Deny update for all usersUPDATEInterdire updateRestrictiveusing: false
Deny delete for all usersDELETEInterdire deleteRestrictiveusing: false

À faire aussi pour la table reponse

Répétez exactement les mêmes étapes pour la table reponse.

attention

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.

astuce

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

  1. Dans Supabase, allez dans l’onglet Table Editor
  2. Sélectionnez la table question
  3. Cliquez sur RLS Policies
  4. Pour chaque politique, cliquez sur les trois points (…) à droite
  5. Cliquez sur "Edit Policy"
  6. 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 :

  • alter par create
  • question par reponse

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

  1. Dans Supabase, ouvrez l’onglet SQL Editor

  2. 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
    );

    60_reponse_SQL_4_policies.png

  3. Cliquez sur "Run"

  4. 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

    61_reponse_SQL_4_policies.png

  • Cliquez sur le bouton Enable RLS for this table

    62_reponse_SQL_4_policies.png

  • Cliquez sur le bouton Enable RLS

    63_reponse_SQL_4_policies.png

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

64_reponse_SQL_4_policies.png


Vérification

  1. Lancez votre projet Next.js

  2. Vérifiez que les questions s’affichent toujours dans l’interface

    70_verification.png

  • La base est sécurisée pour une utilisation publique
  • Vous avez activé RLS sur les tables question et reponse
  • 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