【入門編】 パスワードリセットトークンのタイミング攻撃(Timing Attack) – オフェンシブセキュリティ & リバースエンジニアリング防御ガイド

「0.1秒の差」が命取り?パスワードリセットの裏側で起きている泥棒のテクニック

こんにちは!セキュリティの世界へようこそ。
今日は、皆さんが普段何気なく使っている「パスワードを忘れた際のリセット機能」に潜む、少しスリリングな攻撃手法についてお話しします。

「パスワードリセットなんて、サーバーが正誤を判定するだけでしょう?」と思っているあなた。実は、その「判定の仕方」一つで、泥棒に家の鍵をこじ開けられるかどうかが決まってしまうんです。

今日は、「タイミング攻撃(Timing Attack)」という、映画のような手法について、一緒に紐解いていきましょう。

—

泥棒は「音」を聞いている:タイミング攻撃の正体

想像してみてください。あなたは今、頑丈な金庫の前にいます。この金庫には4桁の暗証番号を入力するボタンがあります。

もし、あなたが間違った番号を押したとき、金庫が「ブッ」と即座にエラーを返すとします。でも、もし「正解の最初の数字」だけ当たっていたら、金庫は計算のために「コンッ……」とほんのわずかだけ反応が遅れるとしたら……?

泥棒は、この「ほんのわずかな反応の差」をストップウォッチで計ります。
1. 1番目の数字を変えながら反応速度を記録する。
2. もっとも反応が遅かった数字が「正解」だと特定する。
3. 次に2番目の数字を……と繰り返す。

このように、「処理にかかる時間の差(=反応の音)」をヒントに、正解を推測していく手法が「タイミング攻撃」です。コンピュータの世界では、これがナノ秒(10億分の1秒)単位で行われています。

—

なぜプログラムは「時間」を漏らしてしまうのか?

プログラムがパスワードリセットトークンを比較するとき、一般的なコードはこんな書き方をしてしまいがちです。

// ダメな比較例
if ($inputToken === $correctToken) {
    // 一致したらログイン許可
}

このコードの何が悪いのでしょうか?
実は、プログラミング言語の「文字列比較(===)」は、「最初の文字が違っていたら、その瞬間に判定を終了する」という性質を持っています。

  • 1文字目が違う → 0.0001秒で「間違い!」と判断
  • 1文字目だけ合っている → 2文字目を確認するために0.0002秒かかる

この「0.0001秒の差」を攻撃者はネットワーク越しに計測し、「あ、1文字目はこれで合ってるな」と確信を得ていくのです。怖いですよね。

—

防御策:全員を「同じペース」で歩かせる

では、どうすればこの泥棒を追い返せるのでしょうか。答えはシンプルです。「たとえ間違っていても、最後まで律儀に確認作業をやり遂げる」ことです。

これを「定数時間比較(Constant-time comparison)」と呼びます。

たとえ1文字目で違っていることが分かっていても、あえて最後まで比較を続けて、「常に一定の時間をかけて回答する」ようにするのです。そうすれば、攻撃者は「どの文字が合っていたのか」を知る手がかり(反応の差)を一切得られなくなります。

安全な書き方(PHPの例)

PHPには、まさにこの目的のために用意された関数があります。

// 安全な比較の実装
// hash_equals関数を使うことで、中身が違っていても
// 全ての文字を比較し終えるまで処理を止めません。
if (hash_equals($correctToken, $inputToken)) {
    // トークンが一致した場合の処理
} else {
    // 一致しなかった場合の処理
}

この一行に変えるだけで、あなたのサービスは「タイミング攻撃」という高度な泥棒の手口から身を守ることができるようになります。

—

まとめ:セキュリティは「泥臭い」ところから始まる

セキュリティと聞くと、ファイアウォールや高度な暗号化を思い浮かべるかもしれませんが、実は今回のように「比較の仕方を工夫する」といった、地味で丁寧な実装の積み重ねこそが、サービスを守る最強の盾になります。

最後に、今日の内容をまとめておきましょう。

  • タイミング攻撃とは?:処理速度のわずかな差から正解を推測する手法。
  • なぜ起きる?:プログラムが「違った瞬間にあきらめる」効率的な動きをするから。
  • どう防ぐ?:hash_equalsのような「定数時間比較」を使い、常に同じ時間だけ処理させる。

セキュリティ対策は、一度やって終わりではありません。皆さんが書くコードの一行一行が、ユーザーの大切なデータを守る鍵になります。

「効率よりも安全を優先する」という意識を少し持つだけで、あなたの作るサービスは格段に信頼できるものになりますよ。これからも、一歩ずつ一緒に学んでいきましょう!

コメント

タイトルとURLをコピーしました