TOCTOU(time-of-check to time-of-use)は、「確認した時点」と「使う時点」の間に状態が変わってしまう問題です。仕組みと防ぎ方を解説します(攻撃手順は載せません)。
TOCTOUとは
プログラムは「確認して、問題なければ使う」という順序で動くことがよくあります。たとえば「このファイルは書き込んでよいものか確認し、よければ開いて書く」です。ところが、確認と使用の間には小さな時間差があります。その間に別のプログラムや別のリクエストが対象を変えると、確認の結果はもう成り立ちません。
MITREのCWE-367は、これを「資源の状態を確認してから使うまでの間に、確認の結果が成り立たなくなる形で状態が変わる」場合として説明しています。CWE(Common Weakness Enumeration)は、脆弱性の原因となる弱点を分類した共通の一覧です。TOCTOUは、同時に動く処理のタイミングで結果が変わる「競合状態(race condition)」の一種です。
なぜ起きるか(仕組み)
CWE-367によると、この問題が起きると、本来使えない資源に読み書きできてしまう、資源が意図しない形で変更される、ログが残らなくなる、といった影響が出ることがあります。隙間は短くても、大量の処理が同時に動く環境では、偶然ではなく繰り返し起こり得ます。
よく出る場所
| 場所 | 確認 | 使用 | 起きること |
|---|---|---|---|
| ファイル操作 | 存在・権限の確認 | 開く・書く | 確認後に別のファイルに差し替わる |
| Webアプリの在庫・残高 | SELECTで残数を確認 | UPDATEで減らす | 同時の2件が両方とも確認を通り、残数を超えて処理される |
| 決済・申込 | 未処理かを確認 | 処理を実行 | 二重送信で同じ処理が2回走る |
| ファイルのアップロード | 内容を検査 | 保存・公開 | 検査した後に内容が変わる |
アップロードの検査については、ファイルアップロード脆弱性も参照してください。
防御:確認と使用を切り離さない
確認してから使う形をやめる
CWE-367の最も基本的な助言は、使う前に確認をしないことです。確認を挟まずに使い、失敗したらエラーを処理する形にすると、隙間そのものがなくなります。
パスではなくファイルディスクリプタで扱う
ファイルは、まず開いて、開いたファイルディスクリプタに対して状態の確認や書き込みを行います。同じパス名を何度も引くと、そのたびに別の対象を指す可能性があります。シンボリックリンクをたどらない O_NOFOLLOW や、ディレクトリを基準に開く openat も役に立ちます(使える機能はOSにより異なります)。
データベースは条件付き更新とトランザクションで
「確認のSELECT→更新のUPDATE」ではなく、条件を含めた1回のUPDATE(例:残数が1以上のときだけ減らす)にします。複数の文にまたがる場合は、トランザクションと適切な分離レベル、行のロックを使います。
ロックは確認の前にかける
ロックを使うなら、CWE-367のとおり確認より前に行います。確認の後にかけても、確認した対象と使う対象が同じとは限りません。
二重実行は冪等キーで止める
決済や申込のような処理は、リクエストごとに一意のキー(冪等キー)を持たせ、同じキーの処理は1回しか実行しないようにします。
自分のコードで確認する方法
自分が開発・管理するコードで行います。
- 「確認する処理」と「使う処理」が別の呼び出しになっている箇所を探す(ファイルの存在確認→オープン、SELECT→UPDATEなど)
- 見つけたら、確認を外して1つの操作にできるかを考える
- 同じ要求を同時に複数回送るテストを書き、結果が1回分だけ反映されることを確かめる
- 他人のサービスに対して試してはいけません。必ず自分の環境で行います
当サイトの視点:『確認』は『使用』と同じ操作の中に入れる
TOCTOUは「確認を忘れた」問題ではなく、「確認はしているのに、確認と使用が離れている」問題です。そのため、確認のコードを増やしても直りません。直す方向は、確認を別の手順として足すことではなく、確認を使用と同じ不可分な操作の中に入れることです。IDORと並べて、「チェックはあるのに効いていない」型の脆弱性として覚えておくと、レビューで見つけやすくなります。
出典(一次情報)
- MITRE CWE-367: Time-of-check Time-of-use (TOCTOU) Race Condition — cwe.mitre.org(定義、影響、緩和策)
- 具体的な手法(O_NOFOLLOW、openat、冪等キー、トランザクション)は、一般的な実装上の手法として記載しています。使える機能はOSやデータベースにより異なるため、各製品の公式ドキュメントで確認してください
次に読む
- 用語:パストラバーサルとは / IDORとは / OWASP Top 10 とは
- 解説:ファイルアップロード脆弱性
- 用語:CVEとは