Skip to content

Instantly share code, notes, and snippets.

@azu
Last active November 28, 2023 02:22
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save azu/faa7909d32c0ed1ab4fced3ad4ab74d8 to your computer and use it in GitHub Desktop.
Save azu/faa7909d32c0ed1ab4fced3ad4ab74d8 to your computer and use it in GitHub Desktop.
Pre-hijacking Attacksのメモ書きやSSO/パスワードリセット/アカウントマージ周りのチェックリスト

Pre-hijacking Attacksについてのメモ書きです。 元の論文と記事は次のページを読んでください。

Pre-hijacking Attacks はメールアドレスの確認をしないでアカウントを作れるサービスという前提があります。

アカウント作成からそのまま機能を利用できるようにすることで、利用体験をよくするための施策として、メールアドレスの確認のステップを後回し またはしないサービスがあります。 モバイルアプリでアカウント作成時に、メールアプリをわざわざ別で開かせるようなフローを避けたりするためにメールを確認しないでアカウント作成ができるサービスもあります。

例) Dropboxはメールアドレスとパスワードを入力して新規アカウントを作成できる。 このときに、自分が持っていないメールアドレスでもとりあえずアカウントを作成できて、そのままログインできる。

攻撃の種類

📝 メールアドレスと書いてるけど、電話番号 + SMSも基本同じ。ログインするIDという意味合い

1. Classic-Federated Merge Attack:

image

  • 攻撃者は、被害者のメールアドレスを使ってアカウントを作っておく
  • 被害者は、GoogleログインなどのSSOでログインする
  • メールアドレスとIdPのメールアドレスが一致するのでアカウントがマージされる
  • 攻撃者は、メールアドレスと攻撃者が設定したパスワードでログインできるので、マージ後の被害者のアカウントを乗っ取れる
  • 対策:
    • アカウントをマージするときには、サービスのメールアドレスとIdPのメールアドレスをどちらも検証済みであるかを確認する

2. Unexpired Session Identifier Attack:

  • 攻撃者は、被害者のメールアドレスを使ってアカウントを作っておく
  • 攻撃者は、そのままログイン状態を維持するように定期的にアクセスし続ける
  • 被害者が、そのサービスを新規で使おうとして「メールアドレスは既に登録されています」となって「このサービスの使ってたけ?」と思ってパスワードリセットする
  • 被害者が、パスワードリセットしてサービスにログインして利用する
  • パスワードリセット時に、攻撃者がログインしていたセッションが切れないため、被害者が設定した内容を盗み取れる(アカウントも乗っ取れる)
  • 対策:
    • パスワードリセットするときに、セッションもリセットする

3. Trojan Identifier Attack:

image

  • 攻撃者は、被害者のメールアドレスを使ってアカウントを作っておく
  • 攻撃者は、そのアカウントと攻撃者のIdPアカウントを紐づけておく
  • 被害者が、そのサービスを新規で使おうとして「メールアドレスは既に登録されています」となって「このサービスの使ってたけ?」と思ってパスワードリセットする
  • 被害者が、パスワードリセットしてサービスにログインして利用する
  • 攻撃者は、攻撃者のIdPアカウントでサービスにログインできるので、被害者が設定した内容を盗み取れる(アカウントも乗っ取れる)
  • 対策:
    • アカウントをマージするときには、サービスのメールアドレスとIdPのメールアドレスをどちらも検証済みであるかを確認する
  • 📝 Classic-Federated Merge Attack は被害者がSSOでログイン、Trojan Identifier Attackは攻撃者がSSOでログイン の違い
    • どちらもマージの挙動を利用した攻撃
  • 📝 もと論文だと、もう一つの攻撃が含まれていて、サブメールアドレスや電話番号を最初に紐づけておいて、それでリセットする攻撃も同じくTrojan Identifier Attackと言ってる
    • Classic-Federated Merge Attackの対義語として扱った方がいいので、SubProcess Attackみたいな別の名前に分離したい

4. Unexpired Email Change Attack:

  • 攻撃者は、被害者のメールアドレスを使ってアカウントを作っておく
  • 攻撃者は、そのアカウントで攻撃者のメールアドレスに変更の申請をしておく(まだ確定はしない)
  • サービスは、メールアドレスの変更の確認メールを攻撃者のメールアドレスの送信する(まだ確定はしない)
  • 被害者が、そのサービスを新規で使おうとして「メールアドレスは既に登録されています」となって「このサービスの使ってたけ?」と思ってパスワードリセットする
  • 被害者が、パスワードリセットしてサービスにログインして利用する
  • 攻撃者、メールアドレスの変更の確認メールからメールアドレスの変更を確定する
  • 攻撃者は、攻撃者のメールアドレスでログインできるので、被害者が設定した内容を盗み取れる(アカウントも乗っ取れる)
  • 対策:
    • パスワードリセットするときに、メールアドレスの変更を保留している状態もリセットする
    • メールアドレスの変更の有効期限を設定する

5. Non-Verifying IdP Attack:

  • 攻撃者は、メールアドレスの確認をしないIdPで被害者のメールアドレスを使ってアカウントを作成する
  • 被害者は、自分自身のメールアドレスでアカウントを作成して利用する
  • 攻撃者は、被害者のメールアドレスを使ったIdPでサービスにログインしてアカウントをマージさせる
  • 攻撃者は、被害者のアカウントを乗っ取れる
  • 📝 メールアドレスの存在確認などをしてないIdP連携の問題
    • またサービスが、OpenIDのclaimに含まれる email_verified をチェックせずにマージしているとこの問題が起きる
    • マージするときは、そのサービスでメールアドレスが確認ずみ + IdPアカウントのメールアドレスが確認ずみで初めてマージする
    • さらにより良くするには、マージするタイミングで、サービスのメールアドレスに紐づくパスワードをリセット または 再入力して、マージするタイミングでの持ち主をもう一度検証する
  • 対策:
    • そういうメールを検証しないIdPでSSOは実装しない
    • アカウントをマージするときには、サービスのメールアドレスとIdPのメールアドレスをどちらも検証済みであるかを確認する

チェックリスト

メールアドレスの検証前にアカウントを作るサービスの場合

  • メールアドレス未確認のアカウントを定期的に削除する
  • メールアドレス未確認状態での機能を制限する

どちらのケースでも共通でやるべきもの

  • アカウント作成時にreCAPTCHAなどを導入し、機械的にアカウントを作成しにくくする
  • パスワードをリセットすると、そのアカウントのセッションを全て無効にする
  • パスワードをリセットすると、メールアドレスの変更を保留している状態もリセットする
  • パスワードをリセットしたときの通知メールに、紐づくIdPやメールアドレスの情報を掲載する
  • パスワードリセットのトークンには有効期限をつける
    • PINコードの場合は、エントロピーを大きくするか、試行回数の制限もつける
  • パスワードリセットのトークンが利用できるのは一度だけにする
  • アカウントをマージする際には、サービスのアカウントとIdPのアカウントが両方検証ずみアカウントであることを確認する
    • OpenID Connectならclaimのemail_verifiedをチェックする
      • ライブラリがやってくれることもあるが、手動でやらないといけないこともあるので必ず確認する
      • Passport + Googleなら、email配列の要素のverifiedプロパティ
      • Next Auth + Googleならprofile.email_verifiedをチェックする
    • verifiedされていないアカウントはマージしてはいけない
  • アカウントをマージする際には、パスワードをリセットしてメールで送信 or アカウントのパスワードの再入力を求める
    • 📝 これは検証済みのアカウントでも、マージする時点の所有者かどうかは別であるため
    • 非同期でやっていた検証をマージする瞬間は同期的に行うことで問題を軽減するアプローチが必要となってる
      • Classic-Federated Merge Attackの場合に再入力は、被害者が知らないパスワードの入力が必要となるのでマージを止められる
      • Non-Verifying IdP Attackの場合は、攻撃者が知らないパスワードの入力が必要となるのでマージを止められる
    • #796956 Able to Takeover Merchants Accounts Even They Have Already Setup SSO, After Bypassing the Email Confirmation
  • メールアドレスの変更の確認メールは、一定の有効期限をつける
    • 1日以内に確定されないならメールアドレスの変更自体を無効にするなど
  • IdP経由でアカウントを作成した場合、そのアカウントでパスワードリセットはできないようにする
    • IdP経由でアカウントを作成した場合、そのアカウントにはパスワードそのものがないはず
    • パスワードリセットによって、パスワードが設定できてしまうと、パスワードレスじゃなくなる
    • あんまり万能な解決方法がない感じがする
    • IdPのみのアカウント(マージされていないアカウント)の場合は、パスワードリセットは、SSOでログインできる有無のメールをリセットメールの代わりに送信するなど
  • パスワードリセットによって、そのアカウントの存在が判定できないようにする
  • 多要素認証を推奨する
  • 多要素認証を有効化した際に、そのアカウントのセッションを全て無効化する
    • これはセッションを維持し続けた攻撃者の攻撃を防ぐ目的(MFAを突破されないようにするため)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment