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.
#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;
}
Fixed code example 1
In this example, Klocwork no longer reports a defect.
#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;
}
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.
#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);
}
Fixed code example 2
In this corrected example, Klocwork no longer reports a defect.
#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);
}
Related checkers
External guidance
Security training
Application security training materials provided by Secure Code Warrior.
Extension
This checker can be extended through the Klocwork knowledge base. See Tuning C/C++ analysis for more information.