HCC

ハードコードされた資格情報の使用(パスワードおよびユーザー名)

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

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

脆弱性とリスク

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

軽減と防止

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

脆弱コード例 1

この例では、Klocwork は 45 行目で欠陥を報告し、connect_to_db 関数がハードコードされた資格情報を使用して呼び出されていることを示しています。

コピー
   #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[])
  {
        login_t login = {  "username" ,  "password" ,  "localhost"  };

        MYSQL *mysql = connect_to_db(&login);
      
        if  (!mysql) 
        { 
              return  -1;
        }

        work_with_db(mysql);
        mysql_close(mysql);

        return  0;
  }

                                            

修正コード例 1

この訂正例では、Klocwork は、関数 connect_to_db がハードコードされた資格情報を用いて呼び出されていることを報告しません。

コピー
   #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 は、ユーザー資格情報がハードコードされた値と比較される欠陥を5 行で報告します。

コピー
   #include <string>
 
   bool connectToServer(const std::string &userAndPassword)
   {
     if (userAndPassword == "alice:s3cr3t")
       return true;
     return false;
   }

修正コード例 2

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

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

拡張機能

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