メインコンテンツ

要注意のヒープ メモリが解放前にクリアされていません

機密データがメモリ ルーチンでクリアも解放もされていない

説明

この欠陥は、動的に割り当てられたメモリに機密データが含まれており、そのメモリを解放する前に機密データをクリアしなかった場合に発生します。

リスク

メモリ ゾーンが再割り当てされる場合でも、攻撃者は古いメモリ ゾーンにある機密データを検査できます。

修正方法

free を呼び出す前に、memsetSecureZeroMemory を使用して、機密データをクリアしておきます。

すべて展開する

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <pwd.h>

void sensitiveheapnotcleared(const char * my_user) {
    struct passwd* result, pwd;
    long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
    char* buf = (char*) malloc(1024);
    getpwnam_r(my_user, &pwd, buf, bufsize, &result);
    free(buf);
}

この例では、関数でパスワードのバッファーが使用され、関数の終了前にそのメモリが解放されています。しかし、メモリ内のデータは、free コマンドを使用してもクリアされません。

修正 — データを無効化

1 つの修正方法として、データを上書きして機密情報をクリアします。この例では memset を使用して、データをゼロで上書きしています。

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <pwd.h>
#include <assert.h>

#define isNull(arr) for(int i=0;i<(sizeof(arr)/sizeof(arr[0]));i++) assert(arr[i]==0)

void sensitiveheapnotcleared(const char * my_user) {
    struct passwd* result, pwd;
    long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
    char* buf = (char*) malloc(1024);

    if (buf) {
        getpwnam_r(my_user, &pwd, buf, bufsize, &result);
        memset(buf, 0, (size_t)1024);
        isNull(buf);
        free(buf); 
    }
}

結果情報

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

バージョン履歴

R2015b で導入