HCC.PWD

ハードコードされた資格情報の使用(パスワード)

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

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

脆弱性とリスク

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

軽減と防止

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

脆弱コード例 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 = { argv[1], "admin_pwd", "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 は、9 行でユーザーパスワードがハードコードされた値と比較される欠陥を報告します。

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

                                            

修正コード例 2

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

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

拡張機能

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