HCC.PWD

Use of hard-coded credentials (password)

If software contains hard-coded credentials for authentication, the software is highly vulnerable to attacks because a malicious user has the opportunity to extract this information from the executable file.

The HCC.PWD checker detects the use of hard-coded passwords as parameters for authentication functions. The HCC.PWD checker also detects cases where software compares user credentials with internal hard-coded values in back-end applications. Hard-coded credentials may not only be coded as credentials used to authenticate a function; they may also be used as a hard-coded check. If a username or a password of an authentication function is compared to a hard-coded string, this is also a vulnerability. By default, this checker considers the functions from popular software libraries, but can also be configured to detect custom authentication functions.

Vulnerability and risk

The use of hard-coded credentials makes it possible for an attacker to extract the credentials from the executable file and bypass the authentication. Hard-coded credentials create a significant risk that may be difficult to detect and to fix.

Mitigation and prevention

For outbound authentication: store passwords, keys, and other credentials outside of the code in a strongly-protected, encrypted configuration file or database that is protected from access by all outsiders, including other local users on the same system. For inbound authentication: Rather than hard-code a default username and password, key, or other authentication credentials for first time logins, implement a "first login" mode that requires the user to enter a unique strong password or key.

Vulnerable code example 1

In this example, Klocwork reports a defect at line 49.

1   #include <mysql.h>
2    
3   typedef struct 
4   {
5       char *username;
6       char *password;
7       char *host;
8   }
9   login_t;
10 
11  void work_with_db(MYSQL *);
12 
13  MYSQL *connect_to_db(login_t *login)
14  {
15      MYSQL *mysql = NULL;
16 
17      mysql = mysql_init(mysql);
18 
19      if (!mysql) 
20  	{
21          return mysql;
22      }
23 
24      if (!mysql_real_connect(mysql,
25                              login->host,
26                              login->username,
27                              login->password,
28                              NULL,
29                              0,
30                              NULL,
31                              CLIENT_FOUND_ROWS)) 
32  	{
33          return NULL;
34      } 
35      else 
36  	{
37          return mysql;
38      }
39  }
40 
41  int main(int argc, char *argv[])
42  {
43      if (argc < 2) 
44  	{
45          return -1;
46      }
47      login_t login = { argv[1], "admin_pwd", "localhost" };
48   
49      MYSQL *mysql = connect_to_db(&login);
50   
51      if (!mysql) 
52  	{
53          return -1;
54      }
55 
56      work_with_db(mysql);
57      mysql_close(mysql);
58 
59      return 0;
60  }   

Fixed code example 1

In this example, Klocwork no longer reports a defect.

1   #include <mysql.h>
2 
3   typedef struct 
4   {
5       char *username;
6       char *password;
7       char *host;
8   } 
9   login_t;
10 
11  login_t read_and_decrypt_auth_info();
12  void work_with_db(MYSQL *);
13   
14  MYSQL *connect_to_db(login_t *login)
15  {
16      MYSQL *mysql = NULL;
17   
18      mysql = mysql_init(mysql);
19 
20      if (!mysql) 
21  	{
22          return mysql;
23      }
24 
25      if (!mysql_real_connect(mysql,
26                              login->host,
27                              login->username,
28                              login->password,
29                              NULL,
30                              0,
31                              NULL,
32                              CLIENT_FOUND_ROWS)) 
33  	{
34          return NULL;
35      } 
36      else 
37  	{
38          return mysql;
39      }
40  }
41   
42  int main(int argc, char *argv[])
43  {
44    login_t login = read_and_decrypt_auth_info();   
45 
46    MYSQL *mysql = connect_to_db(&login);
47   
48    if (!mysql) 
49    {
50        return -1;
51    }
52   
53    work_with_db(mysql);
54    mysql_close(mysql);
55 
56    return 0;
57  }                    

Vulnerable code example 2

In this example, Klocworks reports at defect at line 9, stating that the user password is compared with a hard-coded value.

1   #include <string>
2    
3   bool _connectToServerImpl(const std::string &user,
4                             const std::string &password);
5 
6   bool connectToServer(const std::string &user,
7                        const std::string &password)
8   {
9     if (password == "no_auth")
10      return true;
11    return _connectToServerImpl(user, password);
12  } 

Fixed code example 2

In this corrected example, Klocwork no longer reports a defect.

1   #include <string>
2 
3   bool _connectToServerImpl(const std::string &user,
4                             const std::string &password);
5    
6   bool connectToServer(const std::string &user,
7                        const std::string &password)
8   {
9     return _connectToServerImpl(user, password);
10  }

Extension

This checker can be extended through the Klocwork knowledge base. See Tuning C/C++ analysis for more information.