
Los enlaces Shared-Base de NocoDB podrían invitar a miembros reales de la base y sobrevivir a la revocación de Share.
Los enlaces de base compartida de NocoDB podrían invitar a miembros reales de la base y sobrevivir a la revocación del enlace
Encontré este problema al revisar NocoDB con una simple pregunta de seguridad en mente:
¿Puede un enlace público de base compartida cruzar el límite entre el acceso temporal compartido y la membresía real autenticada de la base?
En este caso, la respuesta fue sí.
Una sesión de base compartida autenticada únicamente por xc-shared-base-id fue tratada como un visor normal de base a efectos de ACL. Debido a que los permisos de visor aún alcanzaban los endpoints de gestión de miembros, un usuario con solo el UUID de la base compartida podía enumerar los miembros existentes de la base e invitar a una dirección de correo electrónico arbitraria a la base como miembro real.
Ese usuario invitado podía entonces canjear la invitación a través del flujo normal de registro, obtener una cuenta autenticada estándar y mantener el acceso a la base incluso después de que el propietario desactivara el enlace de base compartida.
Ese problema se convirtió en CVE-2026-46552.
Proyecto: NocoDB
Versión afectada validada: 0.301.3
Esto afectó a NocoDB. En su sitio oficial, NocoDB se presenta como confiable para más de 35 000 organizaciones, con más de 20 millones de descargas. El sitio también enumera empresas como Accenture, Western Digital, Hyundai, Walmart, PwC, Bosch y American Express.
enlace público de base compartida -> xc-shared-base-id tratado como visor normal de base -> ACL de visor alcanza endpoints de gestión de miembros -> atacante lista usuarios de la base e invita a un correo arbitrario -> usuario invitado canjea token de registro normal -> acceso autenticado duradero a la base sobrevive a la revocación del enlace compartido
NocoDB es una plataforma de colaboración orientada a bases de datos que expone acceso a bases, uso compartido, gestión de metadatos y flujos de trabajo de membresía de usuarios a través del navegador.
Eso significa que su modelo de uso compartido es un límite de seguridad real.
La pregunta importante aquí no era si los enlaces de base compartida podían leer contenido compartido.
La verdadera pregunta era:
¿Puede un principal de uso compartido público realizar acciones que deberían pertenecer solo a miembros autenticados de la base?
En este caso, sí podía.
Las funciones de uso compartido público son fáciles de subestimar.
Eso es un error.
Una vez que una aplicación admite:
el riesgo principal no es solo la exposición de datos.
El riesgo más fuerte es el colapso de límites:
Ese era el verdadero problema aquí.
No era un error en la validación de inicio de sesión. No era un problema de falsificación de tokens. No era una falla de restablecimiento de contraseña.
Era un clásico fallo de límite de autorización:
No abordé esto sondeando endpoints al azar y esperando que algo interesante respondiera.
El camino más fuerte era identificar primero el límite de confianza de mayor valor.
Para NocoDB, ese era el límite entre:
Esos dos estados no deberían ser intercambiables.
Se supone que un enlace de base compartida representa acceso acotado, revocable y basado en enlaces. No debería poder acuñar nuevos principales de larga duración dentro de la base.
Ese es exactamente el límite que falló aquí.
La vulnerabilidad provenía de cómo el acceso a base compartida se integraba en la ruta normal de ACL.
En el flujo frontend de base compartida, xc-shared-base-id se inyectaba mientras se eliminaban los encabezados de autenticación normales.
Luego, en el backend, BaseViewStrategy aceptaba xc-shared-base-id y traducía el enlace compartido directamente a los roles / base_roles normales derivados de la configuración de la base compartida.
Ese fue el primer problema.
El segundo problema fue que los permisos de nivel de visor aún incluían acciones de gestión de miembros.
En la capa ACL, ProjectRoles.VIEWER podía alcanzar:
baseUserListuserInviteEsos permisos protegían rutas meta normales:
GET /api/v2/meta/bases/:baseId/usersPOST /api/v2/meta/bases/:baseId/usersPor lo tanto, una sesión de uso compartido público podía alcanzar endpoints de membresía destinados a participantes reales de la base.
El último paso estaba en el propio flujo de invitación.
BaseUsersService.userInvite() verificaba el poder del rol y luego creaba:
invite_tokenY para las sesiones de base compartida:
invited_by se convertía en nullporque no había una identidad real de invitador autenticado detrás de la solicitud.
Esa es toda la cadena del error.
Porque la posesión de un enlace de base compartida era suficiente.
El atacante no necesitaba:
xc-authLa cadena de explotación era directa:
Eso convierte el uso compartido por enlace revocable en membresía duradera.
La distinción importante es la persistencia después de la revocación.
No se trataba simplemente de:
"un visor podía llamar a un endpoint de visor"
El principal vulnerable no era un visor autenticado normal.
Era una sesión de uso compartido público.
Eso importa porque la aplicación trató a un principal transitorio y acotado por enlace como si fuera lo suficientemente confiable para:
La verdadera pregunta no era:
"¿Puede un usuario compartido leer datos compartidos?"
La verdadera pregunta era:
"¿Se puede convertir el acceso de uso compartido público en acceso autenticado permanente que sobreviva a la revocación del uso compartido?"
La respuesta fue sí.
Por eso es una vulnerabilidad de autorización real y no solo un comportamiento sorprendente de la aplicación.
Validé esto localmente contra:
0.301.3dac49b0122c5ee655fb8f46a1b6e42dfeec1f3adhttp://127.0.0.1:8080La reproducción fue directa.