Inferring password storage security through maximum password length requirements.

I’d like to follow up on a fairly obvious thought I tweeted today:

If a site has password length limits, it’s probably stored in plaintext. Hashed passwords (of any size) have a predicable length.

Excuse the typo, please. Explanation:

The sane operating procedure for password storage is to use a hash function (md5, sha256, bcrypt and similar) along with a “salt” to one-way hash the password. This hash is a known length, no matter how long the password is. For a hexidecimal md5 sum, it’s 32 characters.  When a user comes back to authenticate, you take the password they supply and the salt, calculate the hash, and match it against the hash you have on file. If the newly calculated sum matches the one you have on file, the user has entered their password properly.

There’s no logical reason to limit a hashed password’s length: a 4 character password and a 4000 character password will both calculate to the same size hash.

So if a website has a maximum password length, it means they are probably NOT hashing it and the limit they apply is to keep you from exceeding the column length of the table they store it in.  @abackstrom pointed out here that it’s probably the same situation for disallowed “special characters” – they shouldn’t care what you enter if all they are doing is hashing your password. If they do, they are probably storing it directly in a database.

Why is this bad? Many obvious reasons:

  • Your unencrypted password is sitting in a database, waiting to be stolen if/when the site in question is compromised,
  • Many people share passwords amongst websites, so a list of email addresses and unencrypted passwords can lead to many more compromised accounts on sites all over the web,
  • It’s unnecessary. There’s almost no valid reason to store an unhashed password, especially with all the excellent authentication frameworks out there.

What can you do?

If you’re a website user, complain! If a website has a maximum password length or a restriction against special characters: contact them! Tell them you don’t appreciate their lax security.  Ask them to support openID, ask them if they store passwords unhashed, just let them know this is important.

If you’re a developer, use an authentication library known to do things right in your language of choice. Don’t write your own, busted, authentication system.

Figuring out what’s behind a listening process without a program / pid.

Say you’re being a good sysadmin and you’re checking out listeners on your machines:

root@deathstar:~# netstat -pant | grep LISTEN
tcp        0      0 *               LISTEN      3947/rsync      
tcp        0      0  *               LISTEN      3826/gmond      
tcp        0      0*               LISTEN      4167/bacula-fd  
tcp        0      0   *               LISTEN      3229/portmap    
tcp        0      0    *               LISTEN      3468/sshd       
tcp        0      0  *               LISTEN      3930/master     
tcp        0      0 *               LISTEN      -               
tcp        0      0 *               LISTEN      3247/rpc.statd  
tcp6       0      0 :::22                   :::*                    LISTEN      3468/sshd       

lolwut is listening on 44572 ?

 lsof -i -n -P | grep 44572

returns nothing! IT MUST BE A ROOTKIT!!eleventy!!!

Wait – maybe portmapper has assigned it to a kernel-level server?

root@deathstar:~# pmap_dump
    100000    2   tcp    111  portmapper
    100000    2   udp    111  portmapper
    100024    1   udp  44915  status
    100024    1   tcp  34271  status
    100021    1   tcp  44572  nlockmgr
    100021    3   tcp  44572  nlockmgr
    100021    4   tcp  44572  nlockmgr

Whew- it’s nlockmgr, part of nfs file locking.

So the moral of the story – just because netstat can’t determine a program or pid doesn’t mean you’re in trouble. Check portmapper’s assignments via pmap_dump first, as it might be innocuous.

Apparently netstat can be made aware of portmapper assignments, but it doesn’t appear it is aware of kernel level services – or – it just doesn’t work for me.

“Secure” http connections over untrusted networks

Oh, ssh. How I love thee.

So I wanted to log in to wordpress blog with a login page NOT behind an HTTPS connection from an “insecure” network – in this case, it was the MBTA’s commuter rail wifi.

SSH supports SOCKS proxy connections and makes this STUPIDLY simple:

ssh -C -D 8000

“-C” turns on compression, “-D 8000” makes the SOCKS proxy connection on localhost’s port 8000.

Then you need to set your local firefox to use “localhost”, port 8000 as a SOCKS proxy. And bang! You’re proxying securely over an insecure network.

Yeah, yeah, the best solution would be to have the target wordpress use SSL, but not every blog can have a dedicated IP.