Hello there, ('ω')ノ
記事:
ねらい
今回のケースはSSO(Single Sign-On)とパスワードレスログイン機能(OTP/メールリンクログイン)の組み合わせに設計不備があり、 攻撃者が別人のアカウントへログインできてしまうという深刻な脆弱性です。
一見「便利なログイン機能」ですが、実装ミスにより SSO認証がすり抜け可能 → アカウント乗っ取り につながります。
全体像(ストーリー)
- アプリにはパスワードなしログイン(OTPログイン)機能がある。
- SSOの設計上、同じメールアドレスに複数アカウントを関連付けることが可能だった。
- 攻撃者は「attacker1」「attacker2」という2アカウントを同じメールで登録。
- OTPログインすると、アカウント選択画面が表示され、リクエストにusernameパラメータが含まれていた。
- その値を被害者のユーザー名に書き換えると、SSOが被害者アカウントへログインを許可。
- → 結果:完全なアカウント乗っ取り(Account Takeover)。
実践:一手ずつ「なぜそうするか」
1) 攻撃準備(同じメールで複数アカウント作成)
操作:
- attacker1(メール:attacker@mail.com)
- attacker2(同じメール:attacker@mail.com)
- なぜ:SSOの設計が「メール」ではなくユーザー名ベースでログインを処理しているため、同一メールで複数アカウントが許可されてしまう。
2) パスワードなしログインを実行
- 操作:メールアドレスを入力 → OTPが届く → 入力。
- 観察:アカウント選択画面に遷移(複数アカウントがある場合のみ表示)。
- なぜ:SSOが「どのユーザー名で入るか」をユーザーに選ばせる仕様になっていた。
3) リクエストをキャプチャ
- リクエスト例:
POST /api/sso/login-without-password/auth
{
"track": 006,
"action": "login-without-password",
"code": "[OTP]",
"token": "22123w2DS4543jg23324e35SD==",
"username": "attacker1"
}
注目:usernameパラメータが明示的に存在。
なぜ:本来サーバが決定すべき「ログイン対象のユーザー名」を、クライアントから送信している。
4) パラメータ改ざん(攻撃の核心)
- 操作:
"username": "victim123"に書き換えて送信。 - 観察:SSOがvictim123のアカウントにログイン成功。
- なぜ:サーバ側でOTPとメールアドレスの整合性を検証していないため。
5) 結果
- 攻撃者はOTPを自分のメールで受け取りながら、他人のアカウントにログインできてしまう。
- → 完全なアカウント乗っ取り。
失敗しやすいポイント(検証時の注意)
アカウントが1つしかない場合 → アカウント選択画面は出ず、そのまま自分のアカウントにログイン → 攻撃は成立しない。
リクエスト改ざんを忘れる → ただOTPを入れても被害者には入れない。必ずBurpなどでusernameを書き換える必要がある。
実務目線の防御策
サーバ側での検証強化 usernameをクライアントから受け取らず、サーバがOTPとメールアドレスから自動で紐づける。
同じメールに複数アカウントを許可しない SSOをメール基盤に統一する。
パラメータ改ざん防御 リクエストに含まれるusernameを信用しない。
まとめ
攻撃者の思考プロセスは次の通り:
- 仕様確認:「パスワードなしログイン」がある → 攻撃対象。
- 仕組み理解:SSOはユーザー名で認証 → 同じメールで複数アカウントOK。
- リクエスト解析:usernameパラメータを発見。
- 改ざん実行:victimのユーザー名に差し替える。
- 成功:SSOをバイパスしてアカウント乗っ取り。
つまり、「ユーザーが送っているパラメータをそのまま信じていないか?」 を常に疑うことが、SSOや認証まわりのバグ発見につながります。
Best regards, (^^ゞ