メインコンテンツ

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

CWE Rule 312

Cleartext Storage of Sensitive Information

R2023a 以降

説明

ルールの説明

The product stores sensitive information in cleartext within a resource that might be accessible to another control sphere.

Polyspace 実装

ルール チェッカーは以下の問題をチェックします。

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

  • スタック内にクリアされていない機密データがあります

すべて展開する

問題

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

リスク

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

修正方法

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);  //Noncompliant
}

この例では、関数でパスワードのバッファーが使用され、関数の終了前にそのメモリが解放されています。しかし、メモリ内のデータは、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); 
    }
}
問題

この問題は、静的に割り当てられたメモリに機密データが含まれており、関数またはプログラムを終了する前に機密データをクリアしなかった場合に発生します。

リスク

パスワードやユーザー情報などの機密情報がスタック内に残っていると、プログラム終了後、攻撃者がその情報にアクセスできるようになります。

修正方法

関数またはプログラムの終了前に、memsetSecureZeroMemory を使用して、機密データを含むメモリ ゾーンをクリアしておきます。

例 — パスワード情報の静的バッファー
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>

void bug_sensitivestacknotcleared(const char * my_user) {
    struct passwd* result, pwd;
    long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
    char buf[1024] = "";
    getpwnam_r(my_user, &pwd, buf, bufsize, &result);
}  //Noncompliant

この例では、静的バッファーがパスワード情報で埋められています。プログラムは、その終了時にスタック メモリを解放します。しかし、データは依然としてメモリからアクセス可能です。

修正 — メモリをクリア

1 つの修正方法として、関数の終了前にメモリを上書きします。この例では、memset を使用してバッファー メモリからデータをクリアしています。

#include <unistd.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 corrected_sensitivestacknotcleared(const char * my_user) {
    struct passwd* result, pwd;
    long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
    char buf[1024] = "";
    getpwnam_r(my_user, &pwd, buf, bufsize, &result);
    memset(buf, 0, (size_t)1024);
    isNull(buf);
}

チェック情報

カテゴリ: Information Management Errors

バージョン履歴

R2023a で導入