CertC++-MSC41

Never hard code sensitive information

Required inputs: IR

Hard coding sensitive information, such as passwords or encryption keys can expose the information to attackers. Anyone who has access to the executable or dynamic library files can examine them for strings or other critical data, revealing the sensitive information. Leaking data protected by International Traffic in Arms Regulations (ITAR) or the Health Insurance Portability and Accountability Act (HIPAA) can also have legal consequences. Consequently, programs must not hard code sensitive information.

Hard coding sensitive information also increases the need to manage and accommodate changes to the code. For example, changing a hard-coded password in a deployed program may require distribution of a patch [ Chess 2007].

Noncompliant Code Example (Hard-Coded Database Password)

This noncompliant code example must authenticate to a remote service with a code, using the  authenticate() function declared below. It passes the authentication code to this function as a string literal.

/* Returns nonzero if authenticated */
int authenticate(const char* code);

int main() {
  if (!authenticate("correct code")) {
    printf("Authentication error\n");
    return -1;
  }

  printf("Authentication successful\n");
  // ...Work with system...
  return 0;
}

The authentication code exists in the program's binary executable and can be easily discovered.

Implementation Details (Unix)

Many Unix platforms provide a  strings utility that prints out all of the ASCII strings in a binary file. Here is the output of running  strings on this program, on an Ubuntu 16.04 platform:

% strings a.out
...
AUATL
[]A\A]A^A_
correct code
Authentication error
Authentication successful
...
%
Compliant Solution

This compliant solution requires the user to supply the authentication code, and securely erases it when done, using memset_s(), an optional function provided by C11's Annex K.


/* Returns nonzero if authenticated */
int authenticate(const char* code);

int main() {
#define CODE_LEN 50
  char code[CODE_LEN];
  printf("Please enter your authentication code:\n");
  fgets(code, sizeof(code), stdin);
  int flag = authenticate(code);
  memset_s(code, sizeof(code), 0, sizeof(code));
  if (!flag) {
    printf("Access denied\n");
    return -1;
  }
  printf("Access granted\n");
  // ...Work with system...
  return 0;
}

Alternatively, the program could read the authentication code from a file, letting file system security protect the file and the code from untrusted users.

Risk Assessment

Hard coding sensitive information exposes that information to attackers. The severity of this rule can vary depending on the kind of information that is disclosed. Frequently, the information disclosed is password or key information, which can lead to remote exploitation. Consequently, a high severity rating is given but may be adjusted downwards according to the nature of the sensitive data. 

Rule Severity Likelihood Remediation Cost Priority Level
MSC41-C High Probable Medium P12 L1
Related Guidelines
SEI CERT Oracle Coding Standard for Java MSC03-J. Never hard code sensitive information
ISO/IEC TR 24772:2010 Hard-coded Password [XYP]
MITRE CWE CWE-259, Use of Hard-Coded Password
CWE-798, Use of Hard-Coded Credentials
Bibliography
[ Chess 2007] Section 11.2, "Outbound Passwords: Keep Passwords out of Source Code"
[ Fortify 2006] "Unsafe Mobile Code: Database Access"



MSC40-C. Do not violate constraints  Rule 48. Miscellaneous (MSC)  Rule 50. POSIX (POS)

Excerpt from SEI CERT C++ Coding Standard [https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/miscellaneous-msc/msc41-c], Copyright (C) 1995-2026 Carnegie Mellon University. See section 9.4. "3rd-Party Licenses" in the documentation for full details.

Possible Messages

Key

Text

Severity

Disabled

assignment

Assigning a literal to a variable holding a password.

None

False

comparison

Comparing a literal to a password.

None

False

key

The string literal might include a private key.

None

False

parameter

Passing a literal to a password parameter.

None

False

return

Returning a literal as a password.

None

False

Options

critical_routines_pattern

critical_routines_pattern : typing.Pattern[str] = 'authenticate'

Routines with a fully qualified name matching this pattern are considered as taking credentials for parameters
 

key_detection_pattern

key_detection_pattern : typing.Pattern[str] = 'BEGIN (.*) PRIVATE KEY'

Regex pattern used to detect the ASCII armor of private keys in string literals
 

suspect_detection_pattern

suspect_detection_pattern : typing.Pattern[str] = 'password'

Objects with identifiers including the pattern are considered suspects for holding credentials