Web Security Academyのラボ 「2FA simple bypass」 は、二段階認証(2FA)が設定されているのに、実際には簡単に回避できてしまうケースを扱ったラボです。
2FAはパスワードが漏れても守れる仕組みとしてよく紹介されます。
しかし、実装方法を間違えると、コードを入力していないのにログイン後のページに入れてしまうことがあります。
今回はこのラボをもとに、なぜ2FAが突破されるのかを整理しながら、WordPressサイトで同じ問題が起きた場合を考えていきます。
ラボの概要ーー2FAを入力しなくてもアカウントページが開く
このラボでは、次の状況からスタートします。
すでにユーザー名とパスワードは分かっている
しかし、2FAコードは分からない
通常であれば、ログイン後に2FAコードを入力しない限りアカウントページには入れません。
ところがこのサイトでは、URLを直接変更するだけでアカウントページにアクセスできてしまいます。
つまり、2FAを入力していないのにログイン後のページが開いてしまうという状態になります。
攻撃の流れーーURLを変更するだけで2FAを回避できる
このラボの攻撃はとてもシンプルです。
特別なツールは必要なく、ブラウザだけで再現できます。
【攻撃の流れ】
ログイン画面
↓
ユーザー名+パスワード入力
↓
2FA入力画面が表示
↓
URLを /my-account に変更
↓
アカウントページが表示される
本来であれば、2FAコードを入力しない限りアカウントページには進めないはずです。
しかし、このサイトでは、URLを直接変更するとそのままページが開いてしまいます。
つまり、サーバー側で「2FA認証が完了しているか」が確認されていません。
なぜ2FAが突破されるのかーー認証フローの設計ミス
この問題の原因は、認証処理の順番にあります。
このサイトでは、次のような流れで処理が行われています。
ユーザー名とパスワードを確認
↓
ログインセッションを作成
↓
2FAコード入力を要求
ここで問題になるのは、ログインセッションが先に作られていることです。
セッションとは、ユーザーがログインしている状態をサーバーが記録しておく仕組みです。
ログインセッションが作られてしまうと、そのユーザーは「ログイン済み」として扱われます。
そのため、2FAを入力していなくてもログイン後のページにアクセスできてしまいます。
本来は、
ログイン
↓
2FA確認
↓
ログイン完了
という順番で処理される必要があります。
ラボ名の意味ーー2FA simple bypassとは何か
ラボ名の「2FA simple bypass」を分解すると次の意味になります。
2FA:二段階認証
simple:単純な
bypass:回避
つまり、このラボは「二段階認証を簡単に回避できる状態」を示しています。
特別な攻撃テクニックではなく、ログインフローの設計ミスだけで突破できるのがポイントです。
なぜこれはビジネスロジック脆弱性なのか
この問題はプログラムのバグではありません。原因はシステムの設計です。
本来の認証フローは次のように設計されるべきです。
ログイン
↓
2FA確認
↓
ログイン完了
しかしこのサイトでは、
ログイン
↓
ログイン状態になる
↓
2FA入力画面
という順番になっていました。
つまり、「2FAを通過していなくてもログイン状態になっている」というロジックになっています。
こうした処理の順番のミスは、コードの細かいバグではなく、システム設計の問題です。
そのためビジネスロジック脆弱性に分類されます。
WordPressに置き換えた場合の具体例ーー2FA未完了でもマイページが開いてしまう
この問題をWordPressサイトに置き換えて考えてみます。
例えば、WooCommerceや会員サイトでは次のようなログインフローが一般的です。
ログイン
↓
2FAコード入力
↓
マイページ(/my-account)
しかし、2FAの確認が正しく行われていない場合、次のような状態になる可能性があります。
【WordPressで起きる可能性】
ログイン成功
↓
2FA入力画面
↓
ユーザーが /my-account を直接開く
↓
マイページが表示される
この場合、ユーザーは2FAコードを入力していないにもかかわらず、ログイン後のページにアクセスできてしまいます。
例えば、次のような情報が表示される可能性があります。
- 注文履歴
- プロフィール情報
- 会員限定コンテンツ
WordPressでは、ログイン後にアクセスできるページが複数存在するため、認証フローの設計を間違えるとこのような問題が発生する可能性があります。
WordPressでの対策ポイントーー2FA未完了ユーザーのアクセスを制御する
WWordPressで2FAを導入する場合、重要なのは「ログインしているか」だけではありません。
2FA認証が完了しているかどうかを確認することが必要です。
理想的な認証フローは次のようになります。
ログイン成功
↓
2FA認証
↓
ログイン完了
↓
マイページへアクセス可能
そしてログイン後のページでは、次のような制御を行います。
- 2FA未完了 → 2FA入力画面へ戻す
- 2FA完了 → マイページや管理画面へアクセス可能
つまり、ログイン状態だけではなく、2FA認証の完了状態をページごとに確認する設計が重要になります。
設計視点で見る問題点ーーログイン状態と2FA状態のズレ
このラボの本質は、認証状態の管理にあります。
ログインと2FAは別の処理なので、設計を間違えると状態がズレてしまいます。
今回のケースでは、
- ログイン状態
- 2FA状態
この2つが分離していました。
その結果、2FAを通過していないユーザーでもログイン後のページにアクセスできてしまいました。
設計視点で整理するーー認証フローで確認すべき5つのポイント
認証機能を設計する場合は、次のポイントを確認する必要があります。
- ログインと2FAの状態が分離していないか
- 2FA完了フラグを確認しているか
- URL直接アクセスでページが開かないか
- 認証状態をページごとに確認しているか
- ログインフローが途中でスキップできないか
こうしたチェックを行うことで、今回のような問題を防ぐことができます。
セキュリティ診断で確認されるポイント
実際のセキュリティ診断では、次のような部分がチェックされます。
- 2FA画面をスキップできないか
- URL直接アクセスでログインページが開けないか
- ログインセッションの作成タイミング
- 2FA未完了ユーザーのアクセス制御
- ログイン後ページへの直接アクセス
2FAは導入しているだけでは安全とは言えません。
ログインフローの設計まで含めて確認する必要があります。
まとめーー2FAは設定するだけでは安全にならない
今回のラボのポイントはとてもシンプルです。
2FAを入力していなくてもログイン状態になっていた、という設計ミスです。
二段階認証は強力なセキュリティ対策ですが、ログインフローの設計を間違えると意味がなくなります。
特にWordPressでは、2FAプラグインや独自ログイン機能を使う場合に、認証の状態管理が正しく行われているかを確認することが重要です。
