WebVulnerabilities

TOCTOU攻撃について

概要

TOCTOU(Time-of-Check to Time-of-Use)攻撃は、チェックと使用の間にタイミングの差がある際に発生する脆弱性です。具体的には、システムがあるリソースの状態をチェック(確認)してからそのリソースを使用(利用)するまでの間に、攻撃者がそのリソースを変更することで、システムが意図しない操作を行うことを狙った攻撃です。TOCTOU攻撃は、ファイルシステム操作、メモリ管理、アクセス制御などで発生することがあります。


脆弱性を持つコードの例と攻撃手法

PHP

脆弱なコード:

<?php
$file = 'user_data.txt';

if (is_writable($file)) {
    // ファイルが書き込み可能と判断した後にファイルを開く
    file_put_contents($file, "New data", FILE_APPEND);
}
?>

攻撃手法: 攻撃者は、is_writable()のチェックが行われた後、file_put_contents()が呼び出される前に、別のプロセスでファイルのパーミッションを変更することで、意図的に不正なファイルにデータを書き込ませることができます。

Python

脆弱なコード:

import os

file_path = "user_data.txt"

if os.access(file_path, os.W_OK):
    # 書き込み可能か確認した後にファイルを開く
    with open(file_path, 'a') as file:
        file.write("New data\n")

攻撃手法: 同様に、os.access()でファイルが書き込み可能と判断された後、攻撃者がファイルを削除し、シンボリックリンクや不正なファイルに置き換えることで、任意のファイルに書き込みが行われる可能性があります。

Node.js

脆弱なコード:

const fs = require('fs');
const filePath = 'user_data.txt';

if (fs.accessSync(filePath, fs.constants.W_OK)) {
    // 書き込み可能か確認した後にファイルを開く
    fs.appendFileSync(filePath, 'New data\n');
}

攻撃手法: fs.accessSync()で書き込み可能なファイルと確認された後、攻撃者がファイルを別のファイルに置き換えることで、意図しないファイルにデータが書き込まれる可能性があります。

Java

脆弱なコード:

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class TOCTOUExample {
    public static void main(String[] args) {
        File file = new File("user_data.txt");

        if (file.canWrite()) {
            try {
                FileWriter writer = new FileWriter(file, true);
                writer.write("New data\n");
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

攻撃手法: canWrite()でファイルが書き込み可能と確認された後に、攻撃者がファイルをシンボリックリンクや不正なファイルに変更することで、任意のファイルにデータが書き込まれる危険があります。


防止策

  1. アトミック操作の使用:
    • チェックと使用の間に時間差が生じないように、アトミックな操作を利用する。例えば、ファイルを開くときにO_EXCLフラグを使用することで、ファイルが存在しない場合のみ新しいファイルが作成されるようにする。
    • Pythonではos.open()を使い、os.O_CREAT | os.O_EXCLをフラグとして指定する方法がある。
  2. ファイルロックの使用:
    • ファイルを操作する際にロック機構を導入することで、他のプロセスが同時に操作できないようにする。
    • PHPではflock()、Pythonではfcntlモジュール、JavaではFileLockクラスを使用してファイルロックを実装できる。
  3. 一時ファイルの使用:
    • 一時ファイルにデータを書き込んだ後で、安全に目的のファイルと置き換える手法も有効です。この方法では、攻撃者が目的のファイルにアクセスできる時間が大幅に減少します。
  4. 再検証:
    • リソースを使用する直前にもう一度検証を行い、リソースが安全であることを確認する。例えば、ファイルを開いた後にそのパスや状態を再度チェックします。
  5. 権限を慎重に管理する:
    • 不必要に高い権限でファイルやリソースにアクセスしないようにし、アクセス権限を最小限にすることで、被害を限定する。

TOCTOU攻撃は、システムがリソースをチェックするタイミングとそれを使用するタイミングの間に生じるタイミングの問題を悪用するものです。上記の防止策を適切に実装することで、この脆弱性を効果的に緩和することが可能です。

レースコンディション攻撃とTOCTOU(Time-of-Check to Time-of-Use)攻撃は、いずれもタイミングに依存する脆弱性を悪用する攻撃ですが、その焦点や発生の仕方にはいくつかの違いがあります。

レースコンディション攻撃

概要:
レースコンディション攻撃は、複数のプロセスやスレッドが同時に同じリソースにアクセス・操作を行う際に、タイミングの競合が発生することで、不整合な状態や予期しない結果を引き起こす脆弱性を悪用する攻撃です。複数のプロセスが互いに競合し、同じリソースに対する操作順序が予期しない形で行われることが原因です。

例:

攻撃の特徴:


TOCTOU攻撃

概要:
TOCTOU攻撃は、あるリソースに対してチェック(確認)が行われ、その後そのリソースが使用されるまでの間に、攻撃者がリソースの状態を変更することで、システムが意図しない操作を行わせる脆弱性を悪用する攻撃です。チェックと使用の間のタイミングの差を狙って攻撃が行われます。

例:

攻撃の特徴:


違いのまとめ

両者は、タイミングの問題を利用するという点では共通していますが、競合による問題か、タイミング差による問題かという点で区別されます。それぞれの防止策も異なるため、システム設計や実装において注意が必要です。