5 ways that passwords get compromised

Over the last month as I’ve been doing normal updating of passwords I came across several major public company websites that gave me the following error:

The password you entered is invalid. Please enter between 8 and 20 characters or numbers only.

Anyone that knows anything about “Passwords 101” knows if you go with a minimum of 8 characters and/or numbers it could problematic if someone hacked into the password database. Security experts say that excellent password security includes alphabetical, numeric as well as non-alpha-numeric characters. A password of 8 characters and/or number could be hacked in micro-seconds.

This nicely dovetails with a number of conversations that I’ve had about this recently, and there is so much speculation about password security that I felt compelled to list the potential security holes for passwords. There is very little that you can do beyond minding your own passwords strength. The rest is up the companies and organizations that host your data. Here’s my list of the most common ways that passwords can get compromised.

Inadequate passwords – I suppose it makes sense to start off my list with this topic. But first I have a few important words about password strength. Simple passwords, such as those containing a limited amount of numbers and letters, for example “Test1234”, can be cracked in milliseconds on a typical laptop. When criminals get ahold of a username/password list the first they do is called a dictionary attack in which they try to compromise the easiest to break passwords first.

Unencrypted passwords stored on database – Not encrypting passwords in some way is the same thing as leaving the keys in the ignition of your car with the door unlocked. This is like ice cream to anyone that has access to the database, legally or illegally. They can simply download the ready-to-use user names and passwords.  It doesn’t matter how sophisticated of a password you have if it’s simply unencrypted. There is no way for the user to know if the passwords are encrypted or not, it’s completely up to the IT department that controls the database.

Phishing virus – This virus can provide usernames and passwords for a targeted organization. The intent of this virus is to trick someone into entering their username and password on a fake website that mimics another website, such as an email logon screen. Once someone enters their credentials, they are immediately available to the criminals. The best prevention against phishing viruses is to not open any suspicious attachments and to keep your virus software up to date. There is not a 100% cure against getting a phishing virus since any attachment, even from legitimate sources, could be compromised. But, a good start is not opening ones from someone you don’t know or one that has a suspicious sounding name. Trust your instincts.

Keystroke loggers – This is a spy program that can be installed on any computer. They can be very hard to detect and they do exactly as advertised: they log everything you do on a computer and then they typically relay that information to somewhere else on the internet where your data can examined. The best protection against keystroke loggers, and viruses as well, is a multi-faceted approach: anti-virus programs, spyware sweepers and software firewalls. In addition to that, occasionally viewing which programs are running on your computer and researching any program names you don’t recognize.

Network Sniffers – Sniffer software can monitor all internet traffic over a network.  Network sniffers can easily compromise public WiFi. The person who collects the sniffer data can sift thru the digital traffic information and then siphon out different types of login requests. Once they have the login information, if it’s encrypted they can run cracker programs against the encrypted information. As an internet surfer there is something you can to to help prevent getting your username and password siphoned off: purchase a consumer Virtual Private Network (VPN) product and always use it, especially if you are on an open WiFi at some place like Starbucks or an Airport.

Conclusion

Is there such thing as a truly secure password? Definitely not. This is especially true if the database server containing the password has less-then-adequate security measures in place to protect it from unauthorized intrusion.

Is there anything you can do to protect yourself? Absolutely. My minimum recommendation is to get a password manager program. They can create strong, unique passwords for every website that you need. Some password managers also let you securely share passwords between phone, tablet and laptop. Search for the words “password manager” to find out more. Here’s an article you can peruse as a starting point: pcmag.com. You should also keep your anti-virus software up-to-date and regularly run spyware scanners. Some folks go even one step further and install a software firewall that lets you control all communications to and from your computer. Last, but not least you can use VPN software when surfing the internet.

So what did I do about the websites mentioned above with poor security? In one case I wrote the CEO of the company and I also switched to using the maximum number of characters and numbers, which in the case mentioned above was 20. That website didn’t really store anything vital. In other case, I dropped the website like a lead balloon. If their password security is less-than-optimal I couldn’t help but question and wonder about the rest of their digital information security practices.

Encrypt your OAuth cookies – PHP Example

This post only serves as a reminder that if you decide to use OAuth cookies you should make sure that they are adequately encrypted. I’ve seen a number of web-based OAuth applications recently that left their cookies unencrypted and I wanted to provide a fully working example.

Why should you care?  Any crook with a little bit of knowledge on how to generate header files can use oauth_token and oauth_token_secret and take control of your customers account.

I don’t know why but several of the most popular PHP OAuth libraries don’t mention this as a best practice. So I’m making an effort to shout out that encrypting your cookies is a very good thing to do and it involves the following:

  • Encrypt oath_token and oauth_token_secret
  • Write encrypted values to cookie
  • Read encrypted values when required
  • Provide functionality to delete cookie

Another gotcha is if you allow someone to log out of your app without deleting the cookie, then it’s possible someone else could come along and get the cookie then use it to generate requests on behalf of your client application.

So here’s a fully working PHP example of how to encrypt cookies. You can also access this project through a github repository.

Step 1: generate your key and initialization vector:

<?php
  session_start();
  require_once('config.php');
  require_once('Encrypt.php');
  header('Content-Type: application/json');

  $test = new Encrypt(null,null,DEFAULT_TIME_ZONE);
  echo "\n\n---------\n\nGenerate Key (Base64): " . $test->get_RandomKey();
  echo "\n\n---------\n\nGenerate IV (Base 64): " . $test->get_IV();

?>

Step 2: setup the config file:

<?php

/**
 * @file
 * A single location to store configuration.
 */

//REQUIRED - Encrypt your cookies
//https://si0.twimg.com/images/dev/oauth_diagram.png
//Create your own unique ENCRYPTION_KEY via Encrypt.get_RandomKey()
define('ENCRYPTION_KEY','Q83dBef2tgmHKZ9T1htFA2Y+jZgdler0szN28rjBf8o=');
//Create your own unique initialization vector via Encrypt.get_IV()
define('IV','C2Oez0DLMQ8rCcgYFJwzCw==');
define('DEFAULT_TIME_ZONE','America/Los_Angeles');

?>

Step 3: test ability to set an encrypted cookie and decrypt it.

<?php
session_start();
require_once('config.php');
require_once('Encrypt.php');

$key = base64_decode(ENCRYPTION_KEY);
$iv = base64_decode(IV);
echo "Key: " . $key;
echo "\n\nIV: ". $iv;
$test = new Encrypt($key,$iv,DEFAULT_TIME_ZONE);

if(isset($_COOKIE["twitterapp"]))
{
    header('Content-Type: application/json');

    $retrieved_cookie =  $_COOKIE["twitterapp"];
    echo "\n\nEncrypted value: " . $retrieved_cookie;
    echo "\n\nActual Value: " . "VodG7slxk+w0INvK66gztp4TOLijNzyiWDzI8Z4IU4PTiBJJkRPdkaEbDtXFYUVkCVU=";
    echo "\n\nDecrypted Value: " . $test->decrypt(base64_decode($retrieved_cookie));

}
else
{
    $fake_cookie_string = "VodG7slxk+w0INvK66gztp4TOLijNzyiWDzI8Z4IU4PTiBJJkRPdkaEbDtXFYUVkCVU=";
    $encrypted_cookie = base64_encode($test->encrypt($fake_cookie_string));
    setcookie("twitterapp", $encrypted_cookie, $cookie_life, '/', OAUTH_COOKIE_DOMAIN);
    header('Location: https://your_domain_name/oauthphp/test.php', true, 302);
    exit;

}
?>

And, here is the Encrypt Class:

<?php
class Encrypt{
	/*
	* Basic encryption Class
	* Version: 1.0
	* Author: Andy Gup
	*/
    private $key;
    private $iv;

    function __construct($encryption_key,$iv,$time_zone) {
        $this->key = $encryption_key;
	$this->iv = $iv;
	date_default_timezone_set($time_zone);
     }

     public function encrypt($value){
          $final = null;
          if($value == null || $this->key == null || $this->iv == null)
          {
               header("HTTP/1.0 400 Error");
               echo "\n\n\nERROR: Null value detected: check your inputs";
               exit;
          }
          else
          {
              try
              {
                   $final = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->key, $value, MCRYPT_MODE_CFB,$this->iv);
              }
              catch(Exception $e)
              {
                   header("HTTP/1.0 400 Error");
                   echo "\n\n\nERROR: Failed encryption. " .$e->getMessage();
                   exit;
	      }
          }
          return  $final;
    }

    public function decrypt($value){
        return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->key, $value, MCRYPT_MODE_CFB,$this->iv);
    }

    public function get_RandomKey(){
        $result = openssl_random_pseudo_bytes(32, $secure);
        return base64_encode($result);
    }

    public function get_IV(){
        $size = mcrypt_get_iv_size(MCRYPT_CAST_256, MCRYPT_MODE_CFB);
        return base64_encode(mcrypt_create_iv($size, MCRYPT_RAND));
    }
}
?>

Resources

Github repository

PHP for Windows – the Mcrypt library seems to come with this installation. Mac users may have to install MAMP.

PHP Manual for Mcrypt

OAuth Community

[Modified: April 27, 2013 – added link to github repo.]