ghrc.ioが悪意あるサイトの疑い
(bmitch.net)- 単純なタイプミスである ghcr.io と ghrc.io の取り違えが、深刻なセキュリティ脅威を引き起こす
- ghrc.io は一見すると標準的な nginx サーバーのように見えるが、内部では OCI API を模倣する挙動 が確認されている
- このサイトは www-authenticate ヘッダー を通じて、コンテナクライアントに 機密性の高い認証情報 を送らせようと誘導する
- docker login などで誤って認証情報を入力したり、レジストリを間違えて使用した場合、認証情報の漏えい が発生する可能性がある
- 誤ったサーバーにログインしてしまった場合は、パスワード変更、PAT の失効、GitHub アカウントの不審な活動の確認 が必要
概要
単純なタイプミスによって頻繁に起こり得る ghcr.io と ghrc.io の混同が、非常に 危険なセキュリティ問題 を引き起こしている事例である。多くの開発者やチームが利用する GitHub Container Registry (ghcr.io) のタイプミス版である ghrc.io で、認証情報の窃取の試み が確認された。
ghcr.io とは何か
- ghcr.io は コンテナイメージおよび OCI アーティファクト のための OCI 互換レジストリ
- GitHub の一部であり、多数のオープンソースプロジェクトで 人気のあるレジストリ として使われている
ghrc.io: 表面上の見え方
- ghrc.io にアクセスすると、単なる nginx のデフォルト画面 が表示される
- 典型的な 404 エラーなど、基本的な挙動 は一般的な nginx サーバーと同じ
悪意ある挙動の正体
- 核心的な問題は、
/v2/プレフィックス配下の OCI API 呼び出し時 に現れる - この経路にアクセスすると、
www-authenticateヘッダーと 401 応答により、公式コンテナレジストリと非常によく似た挙動 を示す www-authenticate: Bearer realm="https://ghrc.io/token"ヘッダーが存在する- このヘッダーのため、Docker、containerd、podman、Kubernetes など のクライアントが、ユーザー認証情報を
https://ghrc.io/tokenに 自動送信しようとする - nginx のデフォルト設定にはこのヘッダーは存在しないため、明らかに意図的に構成 されたもの
危険性: 認証情報窃取のシナリオ
- このパターンは タイポスクワッティング (typo-squatting) を利用した認証情報窃取攻撃 と判断される
- 危険が生じるのは、ユーザークライアントが ghrc.io 用の認証情報を入力または保存 している場合に限られる
- 実際に認証情報が露出する可能性のある状況の例
docker login ghrc.ioを実行した場合- GitHub Action 内で
docker/login-actionを使用し、レジストリに ghrc.io を指定した場合 - Kubernetes シークレットに ghrc.io 用のレジストリ認証情報を保存し、イメージの pull を試みた場合
- 単に ghrc.io に対してイメージの push/pull を試みるだけでは、認証情報は露出しない(匿名トークンを試行した後にエラーを返す)
対応策
- ghrc.io に 誤ってログイン したことがあるなら、直ちにパスワードを変更し、使用した PAT (Personal Access Token) を失効させる必要がある
- GitHub アカウントで 不審なログインや悪意ある活動 がないか必ず確認すべき
- 攻撃者はこれを悪用して ghcr.io 上のリポジトリに 悪意あるイメージを追加 したり、アカウントへのアクセス権を取得したりする可能性がある
結論
- ghcr.io に似たアドレスを使う フィッシングサイト に注意が必要
- 認証情報、トークン、パスワードなど セキュリティ情報の管理 について、より厳格な方針が求められる
2件のコメント
単純に github.com のサブドメインに変えるほうがよくないでしょうか。
Hacker Newsのコメント
GitHub Container registry が細分化されたトークンではなく従来のクラシックトークンしかサポートしていない点が深刻だと強調している
関連ドキュメントと Issue のリンクも添えている
公式ドキュメント
コミュニティ議論
ロードマップ Issue
この問題のせいでクラシック PAT を完全に無効化できない状況だ
追加の緩和策としては、セッション有効期間を短く設定し、エンタープライズ SSO で再認証を強制する方法があるが、実際に必要な単一のクラシック PAT のためには煩雑な選択肢だ
誰かが善意で typo ドメインを全部買い集めて Microsoft に渡してくれるといいのにと思う
Microsoft はレジストリ名を変えるべきだと思う
名前があまりにも紛らわしく、私自身も何度もタイプミスしたことがある
ドメインの問題について何度も読み返してようやく把握できたほどで、かなり説得力のある攻撃ベクトルだ
何度試しても失敗し、しまいにはコンピューターを再起動しても同じ問題が起きた
参考になる事例として Stack Overflow の回答 と Docker フォーラムの議論 もある
ghrc.io 関連のコード検索結果 へのリンクを示している
記事で c と r が入れ替わっていることを直接指摘されるまで、問題に気づかなかった
こういうタイプミスは 1 日に 10 回近くやってしまう類いだ
ここでの問題は GitHub のドメイン名がひどいことだ
コンテナレジストリの名前は本当に良くない
過去の Hacker News 議論リンク を共有している
このドメインが dynadot で登録されていることを whois で確認できる
そのため、abuse@dynadot.com に報告する価値はありそうだ
多くのオープンソースプロジェクトでこのドメインが使われていると言及しつつ、コード検索結果 ももう一度共有している
GitHub 内部で大量の自動修正を提案して配布できるツールが必要だ
実際、GitHub のコード検索結果はかなりの規模だと述べている
CI ジョブでタイプミスが起きると大きな問題を引き起こしかねないという懸念を示している
セキュリティ上の価値が低い TLD(トップレベルドメイン)はできるだけ使わないようにしようと助言している
かわいく見せようとする試みよりもセキュリティが優先だ
悪性ドメインの登録解除は .com ほど迅速ではない可能性があるため、米国の Verisign が管理する .com のほうが信頼感があると考えている
イギリス領インド洋地域やコロンビア、アンギラなどに依存するのは不適切だ
ここでの本当のリスクがトークン再利用の問題なのかと質問している
Bearer トークンはパスワードそのものを直接渡すわけではないが、RFC と Mozilla のドキュメントを引用しつつ、実際には認証トークン自体ではなく、認証のために再度トークンを受け取る手続きのほうが問題なのかと疑問を呈している
ドメイン間 OAuth がトークンを再利用しないなら、結局は偽ドメインではトークンを受け取れないのではないかという疑問だ
Bearer トークンを受け取るためのリクエストでは、パスワードや PAT を Basic 認証ヘッダーに base64 エンコードして送るが、実質的には平文で送信される
リクエストを受けると
www-authenticateヘッダーが返され、認証トークンを取得してレジストリアクセスを検証し、その後トークンは期限切れになるが攻撃者が実際のトークンそのものを盗むのではなく、Bearer トークンを受け取るための認証情報そのものを要求できてしまう構造だ