// OTPセキュリティ

OTP実装のベストプラクティス:コード、有効期限、レート制限、フォールバック

ワンタイムパスコードは些細に見えます — 数字を生成し、テキストで送り、確認するだけ。しかしアカウント乗っ取りのバグはその細部に潜みます。このガイドは、OTPフローを本当に安全で使いやすくする判断 — コードのエントロピー、保存、有効期限、レート制限、リトライ、フォールバックチャネル — を扱います。

本物のエントロピーでコードを生成

暗号学的に安全な乱数生成器を使い、予測可能なシードやタイムスタンプ由来の値は決して使わないでください。6桁がセキュリティと使いやすさの一般的なバランスで、より短いコードは安全のためにより厳しいレート制限が必要です。

同じコードを二度送らず、ユーザーIDや連番からコードを推測できるようにしないでください。SMS OTPのセキュリティ全体は、短い寿命の中でコードが予測不能であることにかかっています。

  • 汎用PRNGではなくCSPRNG(例:secrets/cryptoライブラリ)を使いましょう。
  • 6桁が標準;4桁を使うならレート制限と有効期限を強く締めましょう。
  • リクエストごとに1つのコード;新しいコードを発行するとき以前のコードを無効化しましょう。

コードを安全に保存、平文は厳禁

OTPを寿命の短いパスワードのように扱いましょう。生の値ではなく(識別子と有効期限を含む)コードのハッシュを保存し、データベース漏洩が有効なコードを露出させないようにします。タイミング攻撃を避けるため定数時間関数で比較し、使用または期限切れになった瞬間にレコードを削除しましょう。

  • 保存前にコードをハッシュ化し、定数時間で比較しましょう。
  • 各コードを単一のユーザー/セッションと目的に結び付けましょう。
  • 成功、期限切れ、または試行上限到達時に削除しましょう。

短い有効期限を設定

コードは時間単位ではなく分単位で生きるべきです。5〜10分の有効期限が一般的な範囲です:遅れたSMSがまだ届くほど長く、漏れたコードがたいてい既に無効なほど短い。遅いメッセージが壊れたフローに見えないよう、残りの有効時間をユーザーに表示しましょう。

!

短い有効期限を再送クールダウンとセットにしましょう。さもないとメッセージが遅れたときユーザーが再送を連打し、SMSコストが倍増します。

あらゆる次元でレート制限

レート制限は、コードの総当たり推測と送信エンドポイントの悪用(コストが発生し送信者がフラグされることがある)の両方を止める仕組みです。送信と確認の両方で、電話番号ごと、IPごと、アカウントごとに制限しましょう。

  • 確認試行:コードあたりの試行回数(例:5回)を制限し、その後無効化して再送を強制しましょう。
  • 送信リクエスト:送信間のクールダウンと番号あたりの1日上限を設けましょう。
  • グローバルガード:自動化された悪用を鈍らせるIPごと・アカウントごとの上限。
  • 上限が繰り返し当たったら指数バックオフやCAPTCHAを追加しましょう。

リトライとフォールバックチャネルの処理

SMSはベストエフォートなので、良いフローは一部のメッセージが届かないと想定します。クールダウン後の再送を提供し、1〜2回のSMS失敗後はフォールバックチャネル — コードを読み上げる音声通話、WhatsApp、メール — へエスカレーションしましょう。これこそマネージドVerify APIが自動化するものです。

失敗状態を人間的にしましょう:明確な「届きませんでしたか?」の導線、番号を変える方法、繰り返しの失敗後のサポート連絡先。

  1. 1

    最初の試行:SMS

    コードを送り、再送クールダウン付きの見えるカウントダウンを開始しましょう。

  2. 2

    要求時に再送

    クールダウン後の再送を許可し、新しいコードを発行するとき以前のコードを無効化しましょう。

  3. 3

    チャネルのエスカレーション

    繰り返しのSMS失敗後、同じ認証を届ける音声や代替チャネルを提供しましょう。

  4. 4

    出口を提供

    行き止まりではなく、ユーザーが番号を直したりサポートに届けるようにしましょう。

セキュリティを損なわずにUXを改善

小さな工夫が完了率を高めます:モバイルブラウザがコードを読めるようWebOTP APIとSMS自動入力の形式を使い、メッセージの文言を一貫させ(一部のプラットフォームは信頼できる送信者をキャッシュ)、メッセージにコードとアプリ名以外は何も入れないこと。OTPメッセージにリンクは避けましょう — ユーザーをクリックに慣らし、キャリアのスパムフィルターに引っかかります。

  • モバイルでWebOTP/ワンタイムコード自動入力をサポートしましょう。
  • メッセージは最小限に:アプリ名 + コード、マーケティングなし、リンクなし。
  • メッセージ文はローカライズしても、コードの形式は安定させましょう。

よくある質問

OTPはどれくらい有効であるべきですか?+

5分から10分が一般的な範囲です。遅れたSMSに耐えるほど長く、漏れたコードがたいてい既に期限切れなほど短い。遅いメッセージが壊れたフローに見えないよう、常に残り時間を表示しましょう。

確認試行は何回まで許可すべきですか?+

コードあたりの試行を約5回に制限し、その後コードを無効化して新しい送信を要求しましょう。それに、送信・確認の両方に対する番号ごと・IPごと・アカウントごとのレート制限を組み合わせ、総当たりと送信エンドポイントの悪用を止めましょう。

OTPメッセージにリンクを入れるべきですか?+

いいえ。OTPメッセージはアプリ名とコードだけにしましょう。リンクはユーザーをクリックに慣らし、リファラー経由でコードを漏らすことがあり、到達性を損なうキャリアのスパムフィルタリングを頻繁に引き起こします。

SMS OTPだけで十分に安全ですか?+

SMS OTPはパスワードだけより有意な向上ですが、SIMスワップや傍受に弱いです。価値の高いアカウントにはパスキーやTOTPのようなより強い要素を提供し、SMSはフォールバックとして扱いましょう — OTPの代替ガイドを参照してください。

EdgeGigs

OTPフローを最初から正しく実装しよう。

EdgeGigsの審査済み開発者が、安全なコード生成、有効期限、レート制限、フォールバックをあなたのWeb・モバイルアプリに実装します。

EdgeGigsで開発者を探す