メインコンテンツ

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

セキュリティで保護されていない一時ファイルを使用しています

一時的に生成されたファイル名がセキュリティで保護されていない

説明

この欠陥は、セキュリティで保護されていない一時ファイル ルーチンが使用された場合に発生します。

リスク

標準一時ファイル ルーチンで生成されたファイル名を攻撃者が推定すると、その攻撃者には次のことが可能になります。

  • ファイル名が生成される際に競合状態を発生させる。

  • 同じ名前の、悪意のある内容で埋められたファイルを前もって作成する。プログラムがそのファイルを読み込むと、攻撃者のファイルによって悪意のあるコードが投入される可能性があります。

  • 機密データを格納しているファイルへのシンボリック リンクを作成する。プログラムが一時ファイルに書き込みを行うと、機密データが削除されます。

修正方法

一時ファイルを作成するために、POSIX.1-2001 の mkstemp のような、よりセキュリティで保護された標準一時ファイル ルーチンを使用します。

また、フラグが許容されるルーチン (mkostemp など) で一時ファイルを作成する場合は、排他フラグ O_EXCL を使用して競合状態を回避します。

すべて展開する

#define _BSD_SOURCE
#define _XOPEN_SOURCE 
#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int test_temp()
{
    char tpl[] = "abcXXXXXX";
    char suff_tpl[] = "abcXXXXXXsuff";
    char *filename = NULL;
    int fd;
    
    filename = tempnam("/var/tmp", "foo_");
    
    if (filename != NULL)
    {
        printf("generated tmp name (%s) in (%s:%s:%s)\n", 
               filename, getenv("TMPDIR") ? getenv("TMPDIR") : "$TMPDIR",
               "/var/tmp", P_tmpdir);
        
        fd = open(filename, O_CREAT, S_IRWXU|S_IRUSR);
        if (fd != -1)
        {
            close(fd);
            unlink(filename);
            return 1;
        }
    }
    return 0;
}

この例では、open がセキュリティで保護されない一時ファイルを使おうとするため、Bug Finder によってフラグが立てられます。ファイルは排他的権限なしで開かれます。攻撃者はこのファイルにアクセスして、さまざまなリスクを引き起こすことができます。

修正 — O_EXCL フラグを追加

1 つの修正方法として、一時ファイルを開く際に O_EXCL フラグを追加します。

#define _BSD_SOURCE
#define _XOPEN_SOURCE 
#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int test_temp()
{
    char tpl[] = "abcXXXXXX";
    char suff_tpl[] = "abcXXXXXXsuff";
    char *filename = NULL;
    int fd;
    
    filename = tempnam("/var/tmp", "foo_");
    
    if (filename != NULL)
    {
        printf("generated tmp name (%s) in (%s:%s:%s)\n", 
               filename, getenv("TMPDIR") ? getenv("TMPDIR") : "$TMPDIR",
               "/var/tmp", P_tmpdir);
        
        fd = open(filename, O_CREAT|O_EXCL, S_IRWXU|S_IRUSR);
        if (fd != -1)
        {
            close(fd);
            unlink(filename);
            return 1;
        }
    }
    return 0;
}

結果情報

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

バージョン履歴

R2015b で導入