
Portainer CE 2.19.4 にユーザー列挙の脆弱性が発見されました。この問題はユーザー認証プロセス中に発生し、応答時間の差により、リモートの未認証ユーザーがユーザー名が有効かどうかを判断できる可能性があります。
この脆弱性は、Portainer のイシュー #11736 で修正され、Portainer CE バージョン 2.19.5 および 2.20.2 でリリースされました。
私は、Portainer インスタンスのログインページに対してパスワードスプレー攻撃を試みた際に、この脆弱性を発見しました。Portainer アプリケーションのログインフォームに、様々なユーザー名とパスワードを組み合わせた複数のリクエストを送信しました。
ユーザーの存在有無に関係なく、ユーザー名 + パスワードの組み合わせが正しくない場合、Portainer アプリケーションのバックエンドは同じ HTTP ステータスコードで応答します。これは、有効なユーザーの列挙を防ぐ(または妨げる)ための最善のアプローチに準拠しています。
しかし、パスワードスプレーの結果を確認したところ、一部のユーザー名へのログイン試行は一貫して特定の平均時間がかかる一方、他のユーザー名へのログイン試行は一貫して著しく長い平均時間がかかることに気づきました。
システムは既存ユーザーに対してパスワードの有効性をチェックする必要がありますが、ユーザー名が最初から無効な場合はその必要はありません。そのため、ログイン試行時間の平均的な顕著な変化はこれに関係していると推測しました。その後、Portainer CE 2.19.4 のローカルコピーをインストールし、同じ結果になるか動作の再現を試みました。
以下が私が送信したリクエスト形式です。ユーザー名フィールドとパスワードフィールドは、ペイロードを挿入するために選択されました。

これらは、ユーザー名フィールドに挿入したユーザーです。このテストでは、"admin" と "felipe" ユーザーのみが有効でした。リスト内の他のすべてのユーザー名は、既存ユーザーに対応していませんでした。

そして、これらがパスワードフィールドに挿入したパスワードです。

一意のユーザー名とパスワードの組み合わせごとに、サーバーへリクエストが送信されました。結果を以下に示します。

ユーザー名が既存ユーザーに対応する場合、ログイン試行は、存在しないユーザーに対するログイン試行と比較して、一貫して著しく長い時間がかかります。
これは、そのバージョンの Portainer システムが有効なユーザーの列挙に対して脆弱であることを意味します。バックエンドがログイン試行に応答するまでの時間を確認することで、攻撃者はアプリケーションのユーザーを列挙することができます。