
Plausible Analytics master d44e104 - 高 - リモート - 権限の残留 - エディター people HTML 漏洩 転送 nanoid
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · plausible-editor-invite
Plausible Analytics コミュニティエディション、GitHub master d44e104ae3943a9240d5cb6b62e67dff0f069d3a(2026-10-16) - Plausible Insights OÜ
分類: 権限の残留(招待トークンの漏洩)。到達範囲: リモート(そのサイトのゲストエディターまたはチームエディター)。
Sites.list_people/1 は生の guest_invitations.invitation_id と team_site_transfers.transfer_id を選択します。settings_people.html.heex は、保留中のすべての行について、その21文字のnanoidを id="invitation-#{invitation.invitation_id}" に埋め込みます。People設定は SiteController の @special_cased_actions に含まれていないため、AuthorizeSiteAccess は :editor を許可します。ゲストエディターはサイトロール :editor にマッピングされます。ゲストビューアーは404になります。
Nanoid.generate/0 は招待からの登録用ベアラーです。未認証の GET /register/invitation/:invitation_id はidのみで検索します。LiveViewの register は、投稿されたメールアドレスを invitation.email で上書きします。デフォルトのCEは DISABLE_REGISTRATION=invite_only かつ ENABLE_EMAIL_VERIFICATION=false です。承諾はcitextのメール一致による POST /sites/invitations/:id/accept です。
すでにPeople HTMLを閲覧できるゲストエディターが、保留中の所有権移転のnanoidを読み取り、招待された本人として登録し、承諾します。サイトは攻撃者の個人チームへと移行します。
| ID | CVE未割当 |
| CWE | CWE-200 / CWE-269 |
| CVSS | High: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L |
| 製品 | Plausible Analytics |
| 影響範囲 | GitHub master d44e104ae3943a9240d5cb6b62e67dff0f069d3a(2026-10-16)。最後のCEタグ v3.2.1(e4f5a87a5570bd61605217e7ceb376636db8eddb、2026-05-15)は5か月遅れています。SECURITY.md は運用者に :latest の実行を指示しています。ピンは現在のHEADです。CEの MIX_ENV=ce は lib/ のみをコンパイルします。 |
| 認証 | 認証済みのゲストエディター(:guest_member, :editor)またはそのサイトのチームエディター。未認証ではありません。ゲストビューアーでもありません。 |
| ライセンス | GNU Affero GPL v3.0 |
| ラボ | 127.0.0.1:18180(http)18181(postgres)18182(clickhouse http)のみ |
Plausible Analytics leftovers の残留 #1。同じピン、別パック: plausible-traffic-notify(PUT traffic-change-notification の site_id マスアサインメント)。本パックは保留中の所有権移転を窃取するものです。
保留中のゲスト招待および/または所有権移転を持つサイトの、認証済みゲストエディターまたはチームエディター。通常のセッションCookieが必要です。オーナー、管理者、スーパー管理者のLiveViewは不要です。21文字のnanoidを総当たりするのではなく、閲覧が許可されているHTMLからそれを読み取り、招待された本人として登録します。
権限テーブル(網羅的)。Signal-Server Dropwizard admin と同じ基準: メソッド + パス、その呼び出しが付与するもの、偵察 vs 完全性 vs 可用性、ラボで実証済み vs 推測、閉じたままの隣接する攻撃面。
| 軸 | メソッド + パス | 付与されるもの | 検証状況 |
|---|---|---|---|
| Recon | ゲスト/チームエディタとしての GET /:domain/settings/people | 保留中の行が id="invitation-<nanoid>" をレンダリングする。Nanoid は invitation_id または transfer_id。同一サイトのみ。招待者のメールアドレスもテーブル内にある。 | ラボで実証済み。 エディタの people 200 が nanoid Hc8DiBC2q08mv5LFmBysu を漏洩 |
| Recon | 未認証の GET /register/invitation/:id | 登録フォーム上に招待者のメールアドレス。検索は id のみで行われる(find_by_id_unified)。 | ラボで実証済み。 登録 HTML に [email protected] が表示された |
| Integrity | /register/invitation/:id 上の LiveView register | 投稿された user[email] が invitation.email で上書きされる。招待者のアドレスで新しい CE アカウントが作成される。CE のメール認証はデフォルトでオフ。招待制でも :invitation は許可される。 | ラボで実証済み。 [email protected] を投稿したが、保存されたメールは [email protected] だった |
| Integrity | その新しいアカウントとしての POST /sites/invitations/:id/accept | 保留中の所有権移転により sites.team_id が newowner の個人チームへ移動する。移転行は消える。 | ラボで実証済み。 sites.team_id 1 → 2 |
| Integrity | そのメールアドレス宛の保留中のゲスト招待に対して同じ accept を実行 | そのサイトに新しいメンバーシップが付与される(エディタからエディタへの変更は権限の拡大ではない)。そのメールアドレス宛の他の保留中のチーム/ゲスト/移転行も accept 可能になる。 | ソース(InvitationController.accept_invitation) |
| Availability | 移転の accept 後 | 元のチームはサイトを失う。統計は新しいチームで提供され続ける。 | ラボで実証済み。 team_id が移動した |
このピンではクローズのまま
| 軸 | メソッド + パス | クローズされている理由 |
|---|---|---|
| Recon | ゲストビューアの GET /:domain/settings/people | 404。ビューアは :editor ではない。ラボで実証済み。 |
| Integrity | 漏洩した移転 id に対するエディタの POST /sites/invitations/:id/accept | メールアドレスが一致しない。エディタは [email protected] ではない。サイトはチーム 1 に留まる。ラボで実証済み。 |
| Integrity | 有効な招待 id なしでの未認証登録 | check_registration_enabled(:default) と :invitation の比較。whoareme Bug 02、修正済み。 |
| Recon | 21 文字の nanoid ブルートフォース | URL セーフなアルファベット、21 文字。この残存課題の範囲外。 |
| Recon | ClickHouse イベント、SMTP、他サイトの people ページ | 同一サイトのみ。ClickHouse 管理者権限なし。メールボックスの読み取りなし。 |
| Integrity | オーナー/管理者の招待と移転 | 彼らはすでに可能。この残存課題は、それができないエディタに関するもの。 |
| Integrity | スーパー管理者の LiveView、OS シェル、extra/lib の EE SSO | クローズ。CE ラボ。シェルなし。 |
私は、すでに登録済みのユーザーに対する未認証のアカウント乗っ取り、リバースシェル、または ClickHouse のダンプを主張しているわけではない。High のインスタンスは、デフォルト CE(招待制かつメール認証オフ)における保留中のオーナー移転(またはそのメールアドレス宛の他サイト/チームへの招待)である。EE は常に email_verified: false を設定し、/activate には招待者のメールボックスが必要となる。
whoareme Bug 02(2026-05-22 開示)は、有効な招待なしでの招待制 LiveView 登録、および Shield/Goal の site_id マスアサインメントをクローズした。それでも私は現行の master 上で調査を続けた。SECURITY.md は最新の MAJOR.MINOR のみにパッチを当て、運用者には :latest の実行を指示している。最後の CE タグ v3.2.1 は HEAD より 5 か月遅れている。
私は nanoid の invitation_id がデータベースから出ていくすべての箇所を読んだ。accept と register はそれをベアラとして扱う。people 設定はそれを削除ボタンの HTML id= に入れる。削除はオーナー/管理者のみ。id= はそうではない。エディタはそのページを読み込む。
run.sh は、plausible-lab:d44e104ae3943a が存在しない場合にピンをクローンし、DISABLE_REGISTRATION=invite_only で compose を起動し、オーナー / エディタ / ビューア / 保留中の移転をシードし、その後 people の HTML を比較する。
すでに記録済みの誤った道筋:ゲスト登録を自動 accept とみなすこと(ログイン後に POST /sites/invitations/:id/accept が必要);漏洩した移転に対するエディタの accept を窃取とみなすこと(メールアドレスが一致し、移動は起きない);CE の login_ip=5 毎分によるログイン 429(ユーザーごとに 1 セッションを維持すること);ビューアが people を読めるという主張(404)。茶番である。
python3 plausible-editor-invite-Abraxas-Labs.py
または
cd lab
./run.sh
必ず http://127.0.0.1:18180 のみを対象とします。イメージ plausible-lab:d44e104ae3943a(MIX_ENV=ce、ピン d44e104ae3943a9240d5cb6b62e67dff0f069d3a)。Docker が必要です。初回実行時にその SHA で https://github.com/plausible/analytics をクローンし、イメージをビルドします。ランチャーは lab/ に chdir して run.sh を exec します。
IOC editor-people-leak invitation-id=Hc8DiBC2q08mv5LFmBysu
IOC viewer-people http=404
IOC register-email-overwrite [email protected] [email protected]
IOC editor-accept-no-move team_id=1
IOC newowner-accept team_id 1 -> 2
SUCCESS plausible-editor-invite PLAUSIBLE-H02-EDITOR-INVITE-TOKEN-WITNESS
Witness 文字列: PLAUSIBLE-H02-EDITOR-INVITE-TOKEN-WITNESS。オラクルは、accept 後の people HTML の nanoid と sites.team_id です。
エディタが読み込める HTML にベアラ nanoid を配置しないでください。People 設定では、行を invitation_id / transfer_id ではないサーバー側の id でキー付けするか、DOM 用にハッシュ化できます。実際のトークンはオーナー/管理者の削除フォームにのみ保持してください。
エディタ表示のために Sites.list_people/1 で生の invitation_id / transfer_id を選択するのをやめてください。エディタが保留中のテーブルを必要としない場合は、danger-zone と同様に、People をオーナー/管理者として認可してください。
招待からの登録時には、新しいアカウントを CSS id にも存在する nanoid ではなく、ワンタイムのハッシュ化トークンにバインドしてください。
パッチ適用済みビルドに対して loopback クライアント を再実行してください: エディタの people HTML に invitation-<21-char> が含まれてはなりません。People にのみ存在したトークンを Newowner が accept する場合は失敗しなければなりません。