Skip to content

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

References