Hardcoding sensitive information, such as passwords, server IP addresses and encryption keys, can expose the information to attackers. Anyone who has access to the class files can decompile them and consequently can discover the sensitive information. Consequently, hardcoding sensitive information is forbidden.
Hardcoding sensitive information also increases the need to manage and accommodate changes to the code. For example, changing a hardcoded password in a fielded program may require distribution of a patch [[Chess 2007]].
Noncompliant Code Example
This noncompliant code example uses a password field hard coded in a constant String
.
class Password { String password = new String("guest"); public static void main(String[] args) { //.. } }
A malicious user can use the javap -c Password
command to disassemble the class and discover the hardcoded password. The output of the disassembler as shown below, reveals the password guest
in cleartext.
Compiled from "Password.java" class Password extends java.lang.Object{ java.lang.String password; Password(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: aload_0 5: new #2; //class java/lang/String 8: dup 9: ldc #3; //String guest 11: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/String;)V 14: putfield #5; //Field password:Ljava/lang/String; 17: return public static void main(java.lang.String[]); Code: 0: return }
Compliant Solution
This compliant solution retrieves the password from an external file located in a secure directory. Exposure is further limited by clearing the password immediately after use.
class Password { public static void main(String[] args) throws IOException { char[] password = new char[100]; BufferedReader br = new BufferedReader(new InputStreamReader( new FileInputStream("credentials.txt"))); // Reads the password into the char array, returns the number of bytes read int n = br.read(password); // Decrypt password, perform operations for(int i = n - 1; i >= 0; i--) { // Manually clear out the password immediately after use password[i] = 0; } br.close(); } }
To further limit the exposure time of the sensitive password, replace BufferedReader
with a direct NIO buffer, which can be cleared immediately after use.
Noncompliant Code Example (hardcoded database password)
This noncompliant code example hardcodes the user name and password fields in the SQL connection request.
public final Connection getConnection() throws SQLException { return DriverManager.getConnection("jdbc:mysql://localhost/dbName", "username", "password"); }
Note that the one and two argument java.sql.DriverManager.getConnection()
methods can also be used incorrectly. Applets that contain similar code are also unacceptable because they may be executed in untrusted environments.
Compliant Solution
This compliant solution reads the user name and password from a configuration file located in a secure directory.
public final Connection getConnection() throws SQLException { // Username and password are read at runtime from a secure config file return DriverManager.getConnection("jdbc:mysql://localhost/dbName", username, password); }
It is also permissible to prompt the user for the user name and password at runtime.
Risk Assessment
Hardcoding sensitive information exposes that information to attackers.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
MSC03-J |
high |
probable |
medium |
P12 |
L1 |
Related Vulnerabilities
Other Languages
This rule appears in the C Secure Coding Standard as MSC18-C. Be careful while handling sensitive data, such as passwords, in program code
Bibliography
[[Chess 2007]] 11.2 Outbound Passwords: Keep Passwords out of Source Code
[[Fortify 2008]] "Unsafe Mobile Code: Database Access"
[[Gong 2003]] 9.4 Private Object State and Object Immutability
[[MITRE 2009]] CWE-259 "Use of Hard-coded Password," CWE-798, "Use of Hard-coded Credentials"
49. Miscellaneous (MSC) MSC05-J. Store passwords using a hash function