
Plausible Analytics master d44e104 - Élevé - À distance - IDOR - PUT traffic-change-notification site_id affectation de masse
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · plausible-traffic-notify
Plausible Analytics édition communautaire, master GitHub d44e104ae3943a9240d5cb6b62e67dff0f069d3a (2026-10-16) - Plausible Insights OÜ
Classe : IDOR (mass-assignment). Portée : Distante (propriétaire / admin / éditeur d'un site que l'attaquant contrôle déjà).
Plausible.Site.TrafficChangeNotification.changeset/2 caste toujours :site_id. SiteController.update_traffic_change_notification/2 charge la ligne par le domaine du chemin autorisé, puis effectue un Repo.update! de la map du client. La route PUT /sites/:domain/traffic-change-notification/:type se trouve sous :browser + CSRF + AuthorizeSiteAccess [:owner, :admin, :editor, :super_admin]. Le formulaire HTML ne poste que threshold. Phoenix accepte néanmoins des clés supplémentaires.
whoareme Bug 02 a corrigé Shield / Goal site_id de la même manière : lier socket.assigns.site.id, arrêter de caster :site_id. Ce contrôleur n'était pas inclus dans cette passe. L'activation (POST .../enable) estampille site_id: site.id depuis les assigns. L'attaquant active sur son propre site, puis envoie un PUT traffic_change_notification[site_id]=<victim_pk>. Index unique (site_id, type). L'installation par défaut n'a pas de ligne spike/drop, donc la mise à jour réussit et la ligne appartient désormais à la victime. Le nom de la table est l'héritage spike_notifications.
Un éditeur de son propre site réaffecte la ligne de notification spike/drop à un site victime. Les destinataires restent la boîte mail de l'attaquant. Oban envoie à l'attaquant des mails sur le trafic de la victime.
| ID | pas encore de CVE |
| CWE | CWE-915 / CWE-639 |
| CVSS | Élevé : 7.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L |
| Produit | Plausible Analytics |
| Affecté | master GitHub d44e104ae3943a9240d5cb6b62e67dff0f069d3a (2026-10-16). Le dernier tag CE v3.2.1 (e4f5a87a5570bd61605217e7ceb376636db8eddb, 2026-05-15) a cinq mois de retard. CE + EE (lib/, pas extra/lib). |
| Auth | propriétaire / admin / éditeur d'un site qu'ils contrôlent. Viewer ne peut pas. CSRF requis (IDOR de même session). |
| Licence | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1:18183 (http) 18184 (postgres) 18185 (clickhouse http) uniquement |
Reste n°2 de Plausible Analytics leftovers. Même pin, autre pack : plausible-editor-invite (le HTML People divulgue le nanoid de transfert aux éditeurs). Ce pack est le frère Shield/Goal qui caste encore :site_id.
Propriétaire, admin ou éditeur de n'importe quel site qu'il contrôle déjà. Nécessite un cookie de session et le jeton CSRF de cette session. Il n'a pas besoin d'être membre de la victime. Il n'envoie pas de PUT sur le domaine du chemin de la victime (cela renvoie un 404). Il envoie un PUT sur son propre domaine avec une PK entière site_id étrangère.
Table des privilèges (exhaustive). Même barème que Signal-Server Dropwizard admin : méthode + chemin, ce que cet appel accorde, reconnaissance vs intégrité vs disponibilité, prouvé en labo vs déduit, surface adjacente qui reste fermée.
| Axe | Méthode + chemin | Accorde | Provenance |
|---|---|---|---|
| Intégrité | POST /sites/:attacker_domain/traffic-change-notification/:type/enable puis PUT /sites/:attacker_domain/traffic-change-notification/:type avec traffic_change_notification[site_id]=<victim_pk> | Réaffecte la ligne spike_notifications de l'attaquant sur victim.sites.id. Les destinataires restent l'adresse de l'attaquant. Possède l'emplacement unique (site_id, type). Le seuil est choisi par l'attaquant (le labo a utilisé 1). | Prouvé en labo. La ligne 1 a déplacé site_id de 2 → 1, destinataires {[email protected]} |
| Reconnaissance | E-mail Oban TrafficChangeNotifier vers notification.recipients | Sujet Traffic spike on <victim.domain>. Corps : nombre de visiteurs actuel, 3 principales sources, 3 principales pages. Le premier envoi est immédiat (last_sent nil). Répétition au plus toutes les 12 heures. Un seuil de 1 produit un e-mail dès que la victime a un visiteur actuel. Le HTML du tableau de bord / les liens d'installation dans le mail sont omis sauf si le destinataire est membre d'une équipe ou invité (l'attaquant ne l'est pas). | Déduit du code source du notificateur. Mail non capturé en labo (MAILER_ADAPTER=Bamboo.LocalAdapter) |
| Disponibilité | POST .../enable de la victime pour le même type | L'unicité (site_id, type) rejette. La victime ne peut pas activer la fonctionnalité tant que la ligne plantée existe. | Source (unique_constraint) |
| Disponibilité | disable de la victime (delete_all par site_id) | La victime peut supprimer la ligne plantée si elle remarque le destinataire supplémentaire. | Source (disable_traffic_change_notification) |
Reste fermé sur cette version épinglée
| Axe | Méthode + chemin | Pourquoi c'est fermé |
|---|---|---|
| Intégrité | PUT /sites/:victim_domain/traffic-change-notification/:type | Le domaine du chemin est AuthorizeSiteAccess. L'attaquant n'est pas membre. 404 prouvé en labo. attacker-not-member-of-victim=1 |
| Intégrité | Écriture Shield / Goal / funnel / segment / shared-link | whoareme Bug 02 a corrigé ces gestionnaires cast :site_id. Ils lient les assigns. |
| Reconnaissance | Dump ClickHouse, Stats API, HTML du tableau de bord | Pas d'adhésion, pas de lien partagé. Le mail du notificateur omet les liens du tableau de bord pour un non-membre. |
| Intégrité | ingestion tracker | Déjà non authentifié POST /api/event avec un domaine choisi par le client. Ce n'est pas ce reliquat. |
| Intégrité | Repo.update! quand la victime a déjà ce type | 500 sur l'unicité (site_id, type). L'installation par défaut n'a pas de ligne, donc la première plantation fonctionne. |
| Intégrité | viewer du site de l'attaquant | AuthorizeSiteAccess est owner/admin/editor. Un viewer ne peut pas. |
| Intégrité | shell OS, LiveView super-admin | Fermé. Pas de shell. |
Je ne prétends pas obtenir un dump ClickHouse, un reverse shell, ni une connexion au tableau de bord en tant que victime. Le dump est de la reconnaissance de trafic dans un mail que l'attaquant reçoit déjà : domaine, visiteurs en direct, principales sources, principales pages. site_id est la PK entière (énumérable ; whoareme a utilisé site_id=1). Le tableau de bord data-* ne l'émet pas.