Hardcoded Password
What does this mean ?
Hardcoded Passwords are plain text passwords or other secrets that have been hardcoded into source code. Hardcoding a password is never a smart idea. Not only does hardcoding a password allow all project developers to see the password, but it also makes troubleshooting incredibly tough. The password cannot be changed once the code is in production without updating the program. If the password-protected account is compromised, the system's owners will be forced to choose between security and availability.
What can happen ?
Hardcoded passwords are especially risky since they are obvious targets for password guessing attacks, allowing hackers and malware to hijack firmware. If hard-coded passwords are used, attackers will almost certainly get access to the accounts.
Recommendation
- Hardcoded passwords should never be stored in source code.
- Make use of password encryption techniques.
Sample Code
Vulnerable :
using Microsoft.AspNet.Identity;
using System;
using System.Web;
using System.Web.Security;
public class HardCodedCredentialHandler : IHttpHandler
{
public void ProcessRequest(HttpContext ctx)
{
string password = ctx.Request.QueryString["password"];
// BAD: Inbound authentication made by comparison to string literal
if (password == "myPa55word")
{
ctx.Response.Redirect("login");
}
// BAD: Set the password to a hardcoded string literal
MembershipUser user = loadMembershipUser();
user.ChangePassword(password, "myNewPa55word");
}
}
Non Vulnerable :
using Microsoft.AspNet.Identity;
using System;
using System.Web;
using System.Web.Security;
public class HardCodedCredentialHandler : IHttpHandler
{
public void ProcessRequest(HttpContext ctx)
{
string hashedPassword = loadPasswordFromSecretConfig();
// GOOD: Inbound authentication made by comparing to a hash password from a config
if (PasswordHasher.VerifyHashedPassword(hashedPassword, password))
{
ctx.Response.Redirect(VALID_REDIRECT);
}
}
}
Vulnerable :
Connection conn = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost/test?" +
"user=steve&password=blue"); // Sensitive
String uname = "steve";
String password = "blue";
conn = DriverManager.getConnection("jdbc:mysql://localhost/test?" +
"user=" + uname + "&password=" + password); // Sensitive
java.net.PasswordAuthentication pa = new java.net.PasswordAuthentication("userName", "1234".toCharArray()); // Sensitive
Non Vulnerable :
Connection conn = null;
try {
String uname = getEncryptedUser();
String password = getEncryptedPass();
conn = DriverManager.getConnection("jdbc:mysql://localhost/test?" +
"user=" + uname + "&password=" + password);
Vulnerable :
$password = "65DBGgwe4uazdWQA"; // Sensitive
$httpUrl = "https://example.domain?user=user&password=65DBGgwe4uazdWQA" // Sensitive
$sshUrl = "ssh://user:65DBGgwe4uazdWQA@example.domain" // Sensitive
Non Vulnerable :
$user = getUser();
$password = getPassword(); // Compliant
$httpUrl = "https://example.domain?user=$user&password=$password" // Compliant
$sshUrl = "ssh://$user:$password@example.domain" // Compliant
Vulnerable :
const mysql = require('mysql');
const connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '1234',
database : 'mydb'
});
connection.connect();
Non Vulnerable :
const mysql = require('mysql');
const connection = mysql.createConnection({
host : process.env.DB_HOST,
user : process.env.DB_USER,
password : process.env.DB_PASS,
database : process.env.DB_NAME
});
connection.connect();
Vulnerable :
package main
import (
"fmt"
"os"
)
func main() {
databaseName := "NewDb"
secretKey := "123456"
secretPhrase := "ABC"
}
Non Vulnerable :
package main
import (
"fmt"
"log"
"os"
"github.com/joho/godotenv"
)
func getEnvVars() {
err := godotenv.Load("credentials.env")
if err != nil {
log.Fatal("Error loading .env file")
}
}
func main() {
getEnvVars()
databaseName := os.Getenv("DATABASE_NAME")
secretKey := os.Getenv("SECRET_KEY")
secretPhrase := os.Getenv("SECRET_PHRASE")
}
Vulnerable :
class AppBad
def call(env)
req = Rack::Request.new(env)
password = req.params['password']
#Vulnerable
if password == 'myPa55'
[200, {'Content-type' => 'text/plain'}, ['OK']]
else
[403, {'Content-type' => 'text/plain'}, ['Permission denied']]
end
end
end
Non Vulnerable :
class AppGood
def call(env)
req = Rack::Request.new(env)
password = req.params['password']
config_file = YAML.load_file('config.yml')
hashed_password = config_file['hashed_password']
salt = [config_file['salt']].pack('H*')
#Non Vulnerable
hash = OpenSSL::Digest::SHA256.new
dk = OpenSSL::KDF.pbkdf2_hmac(
password, salt: salt, hash: hash, iterations: 100_000, length: hash.digest_length
)
hashed_input = dk.unpack('H*').first
if hashed_password == hashed_input
[200, {'Content-type' => 'text/plain'}, ['OK']]
else
[403, {'Content-type' => 'text/plain'}, ['Permission denied']]
end
end
end