
Les liens de base partagée de NocoDB pourraient inviter de vrais membres de la base et survivre à la révocation du partage
Les liens partagés de base NocoDB peuvent inviter des membres réels et survivre à la révocation du partage
J’ai découvert ce problème en examinant NocoDB, avec une simple question de sécurité en tête :
Un lien de base partagé public peut-il franchir la frontière entre un accès partagé temporaire et une véritable adhésion authentifiée à la base ?
Dans ce cas, la réponse était oui.
Une session de base partagée authentifiée uniquement par xc-shared-base-id était traitée comme un simple visualiseur de base pour les besoins de la liste de contrôle d’accès (ACL). Comme les permissions de visualiseur atteignaient encore les points de terminaison de gestion des membres, un utilisateur disposant uniquement de l’UUID de la base partagée pouvait énumérer les membres existants de la base et inviter une adresse e-mail arbitraire dans la base en tant que membre réel.
Cet utilisateur invité pouvait alors utiliser le jeton d’invitation via le flux d’inscription normal, obtenir un compte authentifié standard et conserver l’accès à la base même après que le propriétaire a désactivé le lien de base partagé.
Ce problème est devenu CVE-2026-46552.
Projet : NocoDB
Version affectée validée : 0.301.3
Cela affectait NocoDB. Sur son site officiel, NocoDB se présente comme étant utilisé par 35 000+ organisations, avec 20 millions+ de téléchargements. Le site mentionne également des entreprises comme Accenture, Western Digital, Hyundai, Walmart, PwC, Bosch et American Express.
lien de base partagée public -> xc-shared-base-id traité comme un simple visualiseur de base -> l’ACL du visualiseur atteint les points de terminaison de gestion des membres -> l’attaquant liste les utilisateurs de la base et invite une adresse e-mail arbitraire -> l’utilisateur invité utilise le jeton d’inscription normal -> l’accès authentifié durable à la base survit à la révocation du lien partagé
NocoDB est une plateforme collaborative orientée base de données qui expose l’accès à la base via navigateur, le partage, la gestion des métadonnées et les workflows d’adhésion.
Cela signifie que son modèle de partage constitue une véritable frontière de sécurité.
La question importante ici n’était pas de savoir si les liens de base partagée peuvent lire le contenu partagé.
La vraie question était :
Un principal de partage public peut-il effectuer des actions qui devraient appartenir uniquement aux membres authentifiés de la base ?
Dans ce cas, oui.
Les fonctionnalités de partage public sont faciles à sous-estimer.
C’est une erreur.
Dès qu’une application prend en charge :
le risque principal n’est pas seulement l’exposition des données.
Le risque plus fort est l’effondrement des frontières :
C’était le vrai problème ici.
Ce n’était pas un bogue dans la validation de connexion. Ce n’était pas un problème de falsification de jeton. Ce n’était pas un défaut de réinitialisation de mot de passe.
C’était un échec classique de frontière d’autorisation :
Je n’ai pas abordé cela en sondant au hasard des points de terminaison en espérant qu’un réponde intéressant.
La voie la plus solide était d’identifier d’abord la frontière de confiance à plus haute valeur.
Pour NocoDB, c’était la frontière entre :
Ces deux états ne devraient pas être interchangeables.
Un lien de base partagée est censé représenter un accès limité, révocable, basé sur un lien. Il ne devrait pas pouvoir créer de nouveaux principaux à longue durée de vie à l’intérieur de la base.
C’est exactement la frontière qui a échoué ici.
La vulnérabilité provenait de la manière dont l’accès à la base partagée était intégré dans le chemin normal de l’ACL.
Dans le flux frontal de la base partagée, xc-shared-base-id était injecté tandis que les en-têtes d’authentification normaux étaient supprimés.
Ensuite, dans le backend, BaseViewStrategy acceptait xc-shared-base-id et traduisait directement le lien partagé en roles / base_roles normaux dérivés de la configuration de la base partagée.
C’était le premier problème.
Le second problème était que les permissions de niveau visualiseur incluaient encore des actions de gestion des membres.
Dans la couche ACL, ProjectRoles.VIEWER pouvait atteindre :
baseUserListuserInviteCes permissions protégeaient les routes meta normales :
GET /api/v2/meta/bases/:baseId/usersPOST /api/v2/meta/bases/:baseId/usersAinsi, une session de partage public était effectivement autorisée à frapper des points de terminaison d’adhésion destinés aux participants réels de la base.
La dernière étape se trouvait dans le flux d’invitation lui-même.
BaseUsersService.userInvite() vérifiait la puissance du rôle, puis créait :
invite_tokenEt pour les sessions de base partagée :
invited_by devenait nullcar il n’y avait pas de véritable identité d’inviteur authentifié derrière la requête.
Voilà toute la chaîne du bogue.
Parce que la possession d’un lien de base partagée suffisait.
L’attaquant n’avait pas besoin de :
xc-authLa chaîne d’exploitation était simple :
Cela convertit le partage de lien révocable en adhésion durable.
La distinction importante est la persistance après révocation.
Ce n’était pas simplement :
« un visualiseur pouvait appeler un point de terminaison de visualiseur »
Le principal vulnérable n’était pas un visualiseur authentifié normal.
C’était une session de partage public.
Cela compte parce que l’application traitait un principal transitoire, limité à un lien, comme suffisamment fiable pour :
La vraie question n’était pas :
« Un utilisateur partagé peut-il lire les données partagées ? »
La vraie question était :
« Un accès de partage public peut-il être converti en un accès authentifié permanent qui survit à la révocation du partage ? »