In my work I often see very bad practices how the users' passwords are treated in web applications. This is a short summary of the current state of the art, how to do it the right way.
2. Often seen situations
●
Passwords are stored in cleartext (EEEEVIL!)
●
Passwords are stored as MD5 hash (slightly
less evil, but not much...)
●
Passwords are sent as GET query parameters
over unencrypted connections
3. Why Care?
Your mama will leak your database
https://www.youtube.com/watch?v=aPWN683KsqU
Need rainbow tables?
https://www.google.com/search?q=md5+5f4dcc3b5aa
4. Rainbows, Brony? Cute!
●
Rainbow Tables are precalculated reverse
lookup tables for hash digests.
●
Just ask Google for the easy ones.
●
Find more specialized tables on shady sites.
●
Calculate your own, while you're not mining for
BitCoins.
●
Having the proper RT enables attackers to find
your users passwords in minutes!
5. So, now? The bare minimum for
your everyday inhouse app:
use Digest::SHA qw(sha256);
sub authenticate {
my ($self, $password) = @_;
if (
$self->password_digest eq
sha256( $self->salt . $self->system->salt . $password )
) {
return 1;
}
return 0;
}
Add salts to your user's passwords!
TWO OF THEM!
And fuckin' use state-of-the-art hashing algorithms!
6. User Salt
●
Generated on password creation/update
●
Unique per user
●
Store with the user in the database (own column
or within password digest column using some
delimiter)
●
Use as much randomness as you can get!
(Quick bet: UUIDs)
●
This effectively destroys attackers possibility of
using a single rainbow table.
7. System Salt
●
Generated once for your application
● Lives outside the database (e.g. config file)
●
Destroys the attackers ability to brute-force the
passwords easily, when they already have the
database dump.
8. For your brand new web 2.0 social
app: KDF
●
Kraft Durch Freude?
●
Key Derivation Functions!
●
Hashing functions are designed to be fast.
●
We don't process passwords by the millions
normally.
●
We don't need it fast!
●
KDFs are about doing it slowly, so to make it
harder for the attacker to crack our passwords.
9. (PB)KDF self-made
sub kdf {
my ($password, $salt, $algo, $iter) = @_;
my $digest = $password;
for (my $i = 0; $i < $iter; $i++) {
$digest = $algo( $salt . $digest );
}
return $digest;
}
You can store the number of needed iterations with the user.
Vary, if you want, but use many! (>1000)
Should I mention that? Use standard KDF libraries of your
language of choice!
10. Transmitting Passwords
●
We ain't gonna transmit passwords in the clear
in 2012!
●
Bring yourself up to speed, how to configure
your environment for SSL/TLS!
Use CAcert for inhouse apps. (I can assure
you, if you want.)
●
StartSSL issues free certs which most
browsers recognize without warning.
11. Transmitting Passwords cont'd
●
If SSL is really too much effort:
●
Do not use credentials in GET queries, these get
stored in HTTP server logs, which will leak!
●
At least, use HTTP digest authentication, which
doesn't transmit the users password.
●
Or use a JavaScript Challenge-Response
Authentication (but be really careful about that!)
12. Transmitting Passwords cont'd
●
If SSL is really too much effort:
●
Do not use credentials in GET queries, these get
stored in HTTP server logs, which will leak!
●
At least, use HTTP digest authentication, which
doesn't transmit the users password.
●
Or use a JavaScript Challenge-Response
Authentication (but be really careful about that!)
13. But I can't log in with other
credentials for debugging now!
●
That's really NOT a good reason to save
passwords in the clear.
●
Add a feature which allows your admin users
to impersonate any other user on the system!
14. Password Strength
●
Educate your users
●
Show password strength meters in your
change-password-forms
●
Disallow weak passwords (server side!!)
15. Web Services
●
Do not use username/password credentials,
especially, if you can't use encryption on
transport.
●
Treating web services like users gives another
attack vector. And there's always this one
place, where you broke your authorization...
●
Treat them with different mechanisms, give
out API keys for them, restrict them to IP
adresses, domain names, time constraints...