Time-of-check to time-of-use
Time-of-check to time-of-use(TOCTTOU、TOCTOU、トックトゥー)とは、ソフトウェア開発において、ある条件(セキュリティ認証など)をチェック (check) したあと、その結果を行使 (use) するまでに変更が発生することで引き起こされるバグの一種である。これは競合状態の一例である。
単純な例として、ユーザーがページを編集できる機能と、管理者がページをロックできる機能をもつWebアプリケーションを考える。まずユーザーがページの編集を要求し、編集フォームが表示される。次にフォームを送信する前に、管理者がページをロックする。しかし編集は既に開始されており、ユーザーがフォームを送信すると、これらの編集は受理される。すなわち、しかるべき権限がチェックされた結果としてユーザーは編集を開始したのであるが、もはや編集が許可されるべきではなくなったときに、その権限は遅れて行使されたのである。
TOCTTOUはUnixのファイルシステムで発生するのが最も一般的であるが、ローカルソケットや不適切なトランザクションなど、他の状況でも発生しうる。OpenSSHの初期のバージョンには、UNIXドメインソケットに悪用可能な競合状態があった[1]。
例
[編集]Unixにおいて、setuid
プログラム中の以下のCコードにはTOCTTOUのバグが存在する。
if (access("file", W_OK) != 0) {
exit(1);
}
fd = open("file", O_WRONLY);
write(fd, buffer, sizeof(buffer));
ここで、access は、このsetuid
プログラムを実行したユーザーが、通常はファイルの書き込み権限を持っているかをチェックしている(すなわち、access
は実効UIDではなく実UIDをチェックする)。
この競合状態は、以下の攻撃に対して脆弱である。
脆弱なコード | 攻撃コード |
if (access("file", W_OK) != 0) {
exit(1);
}
fd = open("file", O_WRONLY);
// 実際には /etc/passwd を上書きしてしまう。
write(fd, buffer, sizeof(buffer));
|
//
//
// 権限チェックのあとで以下を実行する。
symlink("/etc/passwd", "file");
// これによって "file" はパスワードファイルを指すことになる。
//
//
|
この例では、攻撃者はaccess
とopen
の競合状態を悪用し、システムのパスワードデータベースを上書きすることが可能である。すなわちTOCTTOUは、マシンの管理者権限を得る権限昇格攻撃に利用されうる。
一連の命令は正確なタイミングで実行されなければならないが、この条件を整えることは攻撃者にとってそれほど難しいことではない。
この攻撃が示唆するところは、オペレーティングシステムによって管理される状態(この場合はファイルシステム名前空間)がシステムコールの間に変更されないとは保証されないということである。
TOCTTOUの防止
[編集]原理は単純であるが、TOCTTOUを防止、排除することは難しい。一般的なテクニックのひとつは、例外処理を使うことである。
参考文献
[編集]- ^ Acheson, Steve (1999年11月4日). “The Secure Shell (SSH) Frequently Asked Questions”. 2017年3月16日閲覧。