
Plausible Analytics master d44e104 - Alta - Remoto - Privilegio residual - editor personas HTML filtraciones transferencia nanoid
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · plausible-editor-invite
Plausible Analytics edición comunitaria, GitHub master d44e104ae3943a9240d5cb6b62e67dff0f069d3a (2026-10-16) - Plausible Insights OÜ
Clase: Privilegio residual (fuga de token de invitación). Alcance: Remoto (editor invitado o editor de equipo de ese sitio).
Sites.list_people/1 selecciona guest_invitations.invitation_id y team_site_transfers.transfer_id en crudo. settings_people.html.heex coloca ese nanoid de 21 caracteres en id="invitation-#{invitation.invitation_id}" para cada fila pendiente. La configuración de Personas no está en @special_cased_actions de SiteController, por lo que AuthorizeSiteAccess permite :editor. El editor invitado se corresponde con el rol de sitio :editor. El visor invitado devuelve 404.
Nanoid.generate/0 es el portador de registro desde invitación. GET /register/invitation/:invitation_id sin autenticación busca solo por id. El LiveView register sobrescribe el correo enviado con invitation.email. La CE por defecto es DISABLE_REGISTRATION=invite_only y ENABLE_EMAIL_VERIFICATION=false. La aceptación es POST /sites/invitations/:id/accept mediante coincidencia de correo citext.
Un editor invitado que ya puede ver el HTML de Personas lee un nanoid de transferencia de propiedad pendiente, se registra como el invitado y acepta. El sitio pasa al equipo personal del atacante.
| ID | aún sin CVE |
| CWE | CWE-200 / CWE-269 |
| CVSS | Alto: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L |
| Producto | Plausible Analytics |
| Afectado | GitHub master d44e104ae3943a9240d5cb6b62e67dff0f069d3a (2026-10-16). La última etiqueta CE v3.2.1 (e4f5a87a5570bd61605217e7ceb376636db8eddb, 2026-05-15) está cinco meses por detrás. SECURITY.md indica a los operadores que ejecuten :latest. El pin es el HEAD actual. La CE MIX_ENV=ce compila solo lib/. |
| Autenticación | editor invitado autenticado (:guest_member, :editor) o editor de equipo de ese sitio. No sin autenticación. No visor invitado. |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | 127.0.0.1:18180 (http) 18181 (postgres) 18182 (clickhouse http) únicamente |
Residual n.º 1 de Plausible Analytics leftovers. Mismo pin, otro paquete: plausible-traffic-notify (asignación masiva de site_id en PUT traffic-change-notification). Este paquete es el que roba una transferencia de propiedad pendiente.
Editor invitado o editor de equipo autenticado de un sitio que tiene una invitación de invitado y/o una transferencia de propiedad pendiente. Necesita una cookie de sesión normal. Sin propietario, sin administrador, sin LiveView de superadministrador. No fuerza por fuerza bruta el nanoid de 21 caracteres. Lo lee del HTML que tiene permitido cargar y luego se registra como el invitado.
Tabla de privilegios (exhaustiva). Mismo criterio que Signal-Server Dropwizard admin: método + ruta, qué concede esa llamada, reconocimiento frente a integridad frente a disponibilidad, probado en laboratorio frente a inferido, superficie adyacente que permanece cerrada.
| Eje | Método + ruta | Otorga | Procedencia |
|---|---|---|---|
| Recon | GET /:domain/settings/people como invitado/editor del equipo | Las filas pendientes renderizan id="invitation-<nanoid>". El nanoid es invitation_id o transfer_id. Solo el mismo sitio. El correo del invitado también está en la tabla. | Probado en laboratorio. Editor people 200 filtró el nanoid Hc8DiBC2q08mv5LFmBysu |
| Recon | GET /register/invitation/:id sin autenticación | Correo del invitado en el formulario de registro. La búsqueda es solo por id (find_by_id_unified). | Probado en laboratorio. El HTML de registro mostró [email protected] |
| Integridad | LiveView register en /register/invitation/:id | El user[email] enviado se sobrescribe con invitation.email. Nueva cuenta CE en la dirección del invitado. Verificación de correo CE desactivada por defecto. Solo por invitación sigue permitiendo :invitation. | Probado en laboratorio. Se envió [email protected]; el correo almacenado fue [email protected] |
| Integridad | POST /sites/invitations/:id/accept como esa nueva cuenta | La transferencia de propiedad pendiente mueve sites.team_id al equipo personal del nuevo propietario. La fila de transferencia desaparece. | Probado en laboratorio. sites.team_id 1 → 2 |
| Integridad | mismo accept sobre una invitación de invitado pendiente para ese correo | Nueva membresía en ese sitio (editor-por-editor no es una ganancia). Otras filas pendientes de equipo/invitado/transferencia para ese correo también pasan a ser aceptables. | Código fuente (InvitationController.accept_invitation) |
| Disponibilidad | tras aceptar la transferencia | El equipo original pierde el sitio. Las estadísticas siguen sirviéndose en el nuevo equipo. | Probado en laboratorio. team_id movido |
Permanece cerrado en este pin
| Eje | Método + ruta | Por qué está cerrado |
|---|---|---|
| Recon | GET /:domain/settings/people como espectador invitado | 404. El espectador no es :editor. Probado en laboratorio. |
| Integridad | POST /sites/invitations/:id/accept del editor con el id de transferencia filtrado | Coincidencia de correo. El editor no es [email protected]. El sitio permanece en el equipo 1. Probado en laboratorio. |
| Integridad | registro sin autenticación sin un id de invitación válido | check_registration_enabled(:default) vs :invitation. whoareme Bug 02, parcheado. |
| Recon | fuerza bruta de nanoid de 21 caracteres | Alfabeto seguro para URL, 21 caracteres. Fuera de este remanente. |
| Recon | eventos de ClickHouse, SMTP, páginas people de otros sitios | Solo el mismo sitio. Sin admin de ClickHouse. Sin lectura de buzón. |
| Integridad | invitación y transferencia de propietario/admin | Ya pueden. Este remanente es el editor que no puede. |
| Integridad | LiveView de super-admin, shell del SO, SSO EE de extra/lib | Cerrado. Laboratorio CE. Sin shell. |
No estoy afirmando toma de control de cuenta sin autenticación de un usuario ya registrado, una reverse shell ni un volcado de ClickHouse. La instancia High es una transferencia de propietario pendiente (o invitaciones a otros sitios/equipos para ese correo) en CE por defecto: solo por invitación más verificación de correo desactivada. EE siempre establece email_verified: false y /activate necesita el buzón del invitado.