メインコンテンツ

CWE Rule 798

Use of Hard-coded Credentials

R2023a 以降

説明

ルールの説明

The software contains hard-coded credentials, such as a password or cryptographic key, which it uses for its own inbound authentication, outbound communication to external components, or encryption of internal data.

Polyspace 実装

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

  • 定数の暗号キー

  • ハードコードされた機密データ

すべて展開する

問題

この問題は、暗号化キーまたは復号化キーに定数が使用された場合に発生します。

リスク

暗号化キーまたは復号化キーに定数を使用すると、攻撃者はそのキーを簡単に手に入れることができます。

データの暗号化とその後の復号化にはキーを使用します。キーが容易に取得される場合、そのキーを使用して暗号化したデータは安全ではありません。

修正方法

強力な乱数発生器を使用してランダムなキーを作成します。

暗号法的に脆弱な疑似乱数発生器の一覧については、Vulnerable pseudo-random number generator を参照してください。

例 — キーでの定数の使用


#include <openssl/evp.h>
#include <stdlib.h>
#define SIZE16 16

int func(EVP_CIPHER_CTX *ctx, unsigned char *iv){
    unsigned char key[SIZE16] = {'1', '2', '3', '4','5','6','b','8','9',
                                 '1','2','3','4','5','6','7'};
    return EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv, 1);  //Noncompliant
}

この例では、暗号キー key は定数のみを保持します。攻撃者は定数のキーを簡単に手に入れることができます。

修正 — ランダムなキーを使用

強力な乱数発生器を使用して暗号キーを作成します。修正した次のコードでは、openssl/rand.h で宣言されている関数 RAND_bytes を使用します。



#include <openssl/evp.h>
#include <openssl/rand.h>
#include <stdlib.h>
#define SIZE16 16

int func(EVP_CIPHER_CTX *ctx, unsigned char *iv){
    unsigned char key[SIZE16];
    RAND_bytes(key, 16);
    return EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv, 1); 
}
問題

この問題は、機密性の高いデータが文字列リテラルなどとしてコード内で直接露出された場合に発生します。チェッカーは、特定のデータを機密性が高いとして識別し、パスワード暗号化関数などの特定の関数で使用されないようにします。

以下のデータは機密性が高い可能性があります。

データの型情報の機密性を示唆する関数
ホスト名
  • sethostnamesetdomainnamegethostbynamegethostbyname2getaddrinfogethostbyname_rgethostbyname2_r (文字列引数)

  • inet_atoninet_ptoninet_net_ptoninet_addrinet_network (文字列引数)

  • mysql_real_connect mysql_real_connect_nonblockingmysql_connect (第 2 引数)

パスワード
  • CreateProcessWithLogonWLogonUser (第 1 引数)

  • mysql_real_connect mysql_real_connect_nonblockingmysql_connect (第 3 引数)

データベース
  • MySQL: mysql_real_connect mysql_real_connect_nonblockingmysql_connect (第 4 引数)

  • SQLite: sqlite3_opensqlite3_open16sqlite3_open_v2 (第 1 引数)

  • PostgreSQL: PQconnectdb

  • Microsoft SQL:SQLDriverConnect (第 3 引数)

ユーザー名
  • getpw, getpwnam, getpwnam_r, getpwuid, getpwuid_r

ソルトcryptcrypt_r (第 2 引数)
暗号化キーと初期化ベクトル

OpenSSL:

  • EVP_CipherInitEVP_EncryptInitEVP_DecryptInit (第 3 引数)

  • EVP_CipherInit_exEVP_EncryptInit_exEVP_DecryptInit_ex (第 4 引数)

シード
  • srandsrandominitstate (第 1 引数)

  • OpenSSL: RAND_seedRAND_add

リスク

ハードコードされた情報は、コードから生成されたバイナリから問い合わせることができます。

修正方法

機密情報のハードコーディングを回避します。

例 — 文字列リテラルを介して露出された機密データ
// Typically, you include the header "mysql.h" with function and type declarations.
// In this example, only the required lines from the header are quoted.

typedef struct _MYSQL MYSQL;

MYSQL *mysql_real_connect(MYSQL *mysql,
                          const char *host, const char *user, const char *passwd,
                          const char *db, unsigned int port, const char *unix_socket,
                          unsigned long client_flag);

typedef void * DbHandle;
extern MYSQL *sql;

// File that uses functions from "mysql.h" 
const char *host = "localhost";
char *user = "guest";
char *passwd;

DbHandle connect_to_database_server(const char *db)
{
    passwd = (char*)"guest";
    return (DbHandle)
        mysql_real_connect (sql, host, user, passwd, db, 0, 0x0, 0); //Noncompliant 
}

この例では、引数の host (ホスト名)、user (ユーザー名)、および passwd (パスワード) が文字列リテラルで、コードで直接露出されます。

ASCII 文字列の生成されたバイナリを問い合わせると、この情報が公開されます。

修正 – 保護された構成ファイルから機密データを読み取る

1 つの修正方法として、構成ファイルからデータを読み取ります。次の修正例では、関数 connect_to_database_server_init を呼び出すことによって、保護された構成ファイルからホスト名、ユーザー名、およびパスワードがその引数に読み取られる可能性があります。

// Typically, you include the header "mysql.h" with function and type declarations.
// In this example, only the required lines from the header are quoted.

typedef struct _MYSQL MYSQL;

MYSQL *mysql_real_connect(MYSQL *mysql,
                          const char *host, const char *user, const char *passwd,
                          const char *db, unsigned int port, const char *unix_socket,
                          unsigned long client_flag);

typedef void * DbHandle;
extern MYSQL *sql;

// File that uses functions from "mysql.h" 

int connect_to_database_server_init(const char **host,
                                    const char **user,
                                    const char **passwd,
                                    const char **db);

DbHandle connect_to_database_server(const char *db)
{
    const char *host_from_cfg;
    const char *user_from_cfg;
    const char *passwd_from_cfg;
    const char *db_from_cfg;
    if (connect_to_database_server_init(&host_from_cfg,
                                        &user_from_cfg,
                                        &passwd_from_cfg,
                                        &db_from_cfg))
    {
        return (DbHandle)
            mysql_real_connect (sql, host_from_cfg, user_from_cfg, 
                        passwd_from_cfg, db_from_cfg,  0, 0x0, 0);
    }
    else
        return (DbHandle)0x0;
}

チェック情報

カテゴリ: Credentials Management Errors

バージョン履歴

R2023a で導入