メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

デバイス ファイルの I/O 動作が不適切です

セキュリティの脆弱性やシステム障害につながる可能性のある操作

説明

この欠陥は、ファイル名パラメーターを以下の関数に渡す前に、そのファイル名パラメーターでデバイス ファイルが参照されるかどうかをチェックしていない場合に発生します。

  • fopen()

  • fopen_s()

  • freopen()

  • remove()

  • rename()

  • CreateFile()

  • CreateFileA()

  • CreateFileW()

  • _wfopen()

  • _wfopen_s()

デバイス ファイルは、デバイス ドライバーにインターフェイスを提供するファイル システムのファイルです。これらのファイルを使用してデバイスを操作することができます。

デバイス ファイルの I/O 動作が不適切ですは、以下の場合には欠陥を報告しません。

  • 上記にリストした関数を呼び出す前に、stat または lstat ファミリ関数を使用してファイル名パラメーターをチェックしている。

  • 文字列比較関数を使用して、ファイル名をデバイス ファイル名のリストに対して比較している。

リスク

通常のファイルに対してのみ適切な操作をデバイス ファイルに対して実行すると、サービス拒否攻撃、その他のセキュリティ脆弱性、またはシステム障害の原因になる可能性があります。

修正方法

ファイルに対して I/O 操作を実行する前に、以下を行います。

  • stat()lstat()、または同等の関数を使用して、ファイル名パラメーターが通常のファイルを参照しているかどうかをチェックする。

  • 文字列比較関数を使用して、ファイル名をデバイス ファイル名のリストに対して比較する。

すべて展開する

#include <stdio.h>
#include <string.h>

#define SIZE1024 1024

FILE* func()
{

    FILE* f;
    const char file_name[SIZE1024] = "./tmp/file";
    
    if ((f = fopen(file_name, "w")) == NULL) {
        /*handle error */
    };
    /*operate on file */
}

この例では、func() はファイル file_name に対して実行されますが、それが通常のファイルかどうかはチェックされません。file_name がデバイス ファイルである場合、アクセスを試みるとシステム障害が発生する可能性があります。

修正 — fopen() を呼び出す前に lstat() を使用してファイルをチェック

1 つの修正方法として、lstat()S_ISREG マクロを使用してファイルが通常のファイルなのかどうかをチェックします。この解決策は、ファイルがチェックされた後の、 fopen() の呼び出し前の時点で攻撃者によるファイルの改変を許す TOCTOU 競合状態を含みます。この脆弱性を防ぐために、file_name が安全なフォルダー内のファイルを参照することを確認してください。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>

#define SIZE1024 1024

FILE* func()
{

    FILE* f;
    const char file_name[SIZE1024] = "./tmp/file";
    struct stat orig_st;
    if ((lstat(file_name, &orig_st) != 0) ||
        (!S_ISREG(orig_st.st_mode))) {
        exit(0);
    }
    if ((f = fopen(file_name, "w")) == NULL) {
        /*handle error */
    };
    /*operate on file */
} 

結果情報

グループ: セキュリティ
言語: C | C++
既定値: オフ
コマンド ライン構文: INAPPROPRIATE_IO_ON_DEVICE
影響度: Medium

バージョン履歴

R2018b で導入