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 知识库进行扩展。有关详情,请参阅调整 C/C++ 分析。