HCC.USER

ハードコードされた資格情報の使用(ユーザー名)

ソフトウェアに認証用の資格情報がハードコードされている場合、悪意のあるユーザーに実行可能ファイルからこの資格情報を取り出す機会を与えてしまうため、こうしたソフトウェアは攻撃に対して極めて脆弱になります。

HCC.USER チェッカーは、ハードコードされたユーザー名が認証関数のパラメーターに使われている場合にそれを検出します。また HCC.USER チェッカーは、ユーザーの資格情報がバックエンドアプリケーションの内部にハードコードされた値と比較されるケースも検出します。ハードコードされた資格情報は、関数の認証に使用される資格情報としてコード化されるばかりでなく、ハードコードされたチェックにも使用されます。脆弱性は、認証関数のユーザー名またはパスワードがハードコードされた文字列と比較される場合にも存在します。このチェッカーはデフォルトで、人気のあるソフトウェアライブラリからこの関数を検討しますが、カスタム認証関数を検出するよう設定することも可能です。

脆弱性とリスク

ハードコードされた資格情報を使用すると、攻撃者が実行可能ファイルから資格情報を取り出して、正当な認証を迂回することが可能になってしまいます。ハードコードされた資格情報は、検出や修正が困難と予想される著しいリスクを招きます。

軽減と防止

アウトバウンド認証の場合:パスワードやキーなどの認証資格情報は、ソースコード外部の強固に保護され、暗号化された構成ファイル内または同じシステム上のローカルユーザーも含め、すべての外部者によるアクセスから保護されたデータベースに保存されます。インバウンド認証の場合:初回ログイン時のデフォルトのユーザー名、パスワード、キー、その他の認証資格情報をハードコードするより、ユーザーが一意の強力なパスワードやキーを入力する必要がある「初回ログイン」モードを実装してください。

脆弱コード例 1

この例では、Klocwork は 49 行で欠陥を報告します。

コピー
   #include <mysql.h>
 
   typedef struct 
   {
       char *username;
       char *password;
       char *host;
   } 
   login_t;
 
  void work_with_db(MYSQL *);
 
  MYSQL *connect_to_db(login_t *login)
  {
      MYSQL *mysql = NULL;
 
      mysql = mysql_init(mysql);
   
      if (!mysql) 
      {
          return mysql;
      }
   
      if (!mysql_real_connect(mysql,
                              login->host,
                              login->username,
                              login->password,
                              NULL,
                              0,
                              NULL,
                              CLIENT_FOUND_ROWS)) 
      {
          return NULL;
      } 
      else 
      {
          return mysql;
      }
  }
 
  int main(int argc, char *argv[])
  {
      if (argc < 2) 
      {
          return -1;
      }
      login_t login = { "admin", argv[1], "localhost" };
   
      MYSQL *mysql = connect_to_db(&login);
 
      if (!mysql) 
      {
          return -1;
      }
 
      work_with_db(mysql);
      mysql_close(mysql);
   
      return 0;
  }

修正コード例 1

この例では、Klocwork は欠陥を報告しません。

コピー
   #include <mysql.h>
    
   typedef struct 
   {
       char *username;
       char *password;
       char *host;
   } 
   login_t;
 
  login_t read_and_decrypt_auth_info();
  void work_with_db(MYSQL *);
   
  MYSQL *connect_to_db(login_t *login)
  {
      MYSQL *mysql = NULL;
 
      mysql = mysql_init(mysql);
 
      if (!mysql) 
      {
          return mysql;
      }
 
      if (!mysql_real_connect(mysql,
                              login->host,
                              login->username,
                              login->password,
                              NULL,
                              0,
                              NULL,
                              CLIENT_FOUND_ROWS)) 
      {
          return NULL;
      } 
      else 
      {
          return mysql;
      }
  }
 
  int main(int argc, char *argv[])
  {
      login_t login = read_and_decrypt_auth_info();   
 
      MYSQL *mysql = connect_to_db(&login);
  
      if (!mysql) 
      {
          return -1;
      }
 
      work_with_db(mysql);
      mysql_close(mysql);
 
      return 0;
  }

脆弱コード例 2

この例では、Klocwork は、6 行でユーザー名がハードコードされた値と比較される欠陥を報告します。

コピー
   #include <string>
 
   bool connectToServer(const std::string &user,
                        const std::string &password)
   {
     if (user == "admin")
       return true;
     return false;
   }

修正コード例 2

この訂正例では、Klocwork は欠陥を報告しません。

コピー
   #include <string>
    
   namespace database 
   {
     bool checkServerCredentials(const std::string &user,
                                 const std::string &password);
   }
 
   bool connectToServer(const std::string &user,
                        const std::string &password)
  {
    return database::checkServerCredentials(user, password);
  } 

セキュリティトレーニング

Secure Code Warrior が提供しているアプリケーションセキュリティトレーニング教材。

拡張機能

このチェッカーは、Klocwork knowledge base (ナレッジベース) を利用して拡張できます。詳細については、C/C++ 解析のチューニングを参照してください。