Showing posts with label password. Show all posts
Showing posts with label password. Show all posts

Sunday, 14 April 2013

A quick peek at nodeunit

I've been hacking around with node for a while now (as many people have), but because much of it has been just that, hacking, and very little of the code base grows beyond a couple of hundred lines of code, I've not been writing unit tests. tisk tisk.

I'm not really planning anything big in the near future, but if I embark on building something that is more than a prototype or a hack I'm going have to unit test. So tonight I'm going to have a quick poke around to see what folks are using for unit testing node application.

I'm not sure what the de facto framework is, but I'm going to follow the pattern set over the years of _something_Unit. So, I'm going to punt at there being a NodeUnit. Google "nodeunit" -> Bang!

There is already a good article on getting started, so I'm not going to add any value here tbh. But I'll carry on and record my concise notes, just in case I need to refer to them myself in the future.

I'm on Ubuntu, though it shouldn't matter which platform you're on. (if truth be known, I've had some issues with code being cross-platform compatible with node)

$ sudo npm install nodeunit -g

I thought I'd knock up something that is at least vaguely security related. I'm not getting into arguments around random passwords vs memorable passwords, nor am I starting on hashing, salting or key stretching; this is simply something that allows me to test drive nodeunit quickly and simply.

The example is a simple, old-skool password policy. Stuff like:
  • Minimum length
  • Upper case
  • Lower case
  • Numeric
  • Special characters
I'm keeping it simple. Ensure the above criteria are validated. So, here's the code. (there's nothing clever here)

The tests are simple too. I want to ensure the policy is enforced and that nodeunit can handle the tests I want to exercise.
  • If minimum length is not met, throw an error
  • If it is not a string, throw an error
  • If the criteria is not met, fail the test
I added the random generation of test passwords - I thought about using Markov Chains to generate the passwords, but then thought, that's a good subject for a different post.

As an aside, I kinda like the fact that the validator is validating the test utility that generates passwords to be used in the tests, code validating the validation tests...

Anyhoo; running the tests...

$ nodeunit test_validator.js

The code ran first time, surprising since I wasn't using an IDE, it was the old fave TextPad. More surprising though was how quickly it ran; I upped the random generating of passwords to 5,000,000 and it took only 15 seconds to execute. Cool.

So, to summarise my fleeting introduction to nodeunit.
  • It's fast
  • Easy to install
  • Quick to install
  • Easy to understand
  • Fast
I'll kick the tyres of nodeunit a little more in the future should I get more serious with node, and if there are any notable observations I'll add them as a comment to this post.

There are mode frameworks out there too, but from experience, you tend to stick with what works until it doesn't work. So, for me, I think nodeunit will be my de facto node...unit.

Thursday, 21 June 2012

Key Stretching; an example

I've had quite a few questions about my previous post (from June 2010) on Passwords since I recently reposted it.

More specifically the questions and comments were around key stretching.

Q.  But doesn't looping that many times slow the password verification step down?
A.  Well yes.  That's kind of the point.  The user may experience negligible latency during the authentication process, this can be tuned to have no or little effect on the user experience.  This same delay is multiplied by the number of brute force attempts made by the attacker.

Q.  The attacker doesn't need the salt or the algorithm if they are going through the front door?
A.  Agreed.  Which is why you'd have some controls and triggers at the front door to alert when abnormal or atypical behaviour is detected.

Q.  If an attack gains access to a system, surely it's game over for user PII?
A.  The thing I like about key stretching is that a hacker needs to have access to the salt, the hashed password and stretching algorithm.  So, if you store the salt in a different table or even DB than the hashed password, the attacker would need to get their mitts on both tables or both DBs. Gaining visibility of the algorithm means that the attacker would also need to have access to, or knowledge about the specific implementation details; ie the source code. Typical environment configurations ensure that there is no way to get to a development environment from a production environment (and vice versa), making it difficult to gain access to the source.

This is a quick and dirty example of what key stretching would look implemented in Java.


This runs in around 0.75 seconds on my local box. Which means every iteration of a dictionary attack or a brute force attack would take the same time.

Caveat: this is purely an example of how you could implement stretching.

Monday, 21 June 2010

Passwords

Passwords are now so everyday that remembering a dozen or so long, complex password doesn't phase anyone. But why do passwords have to be so long and so complex? Well, you don't want to bad guys to be able to guess it or to apply brute force to 'crack' it and gain access to your private data, do you?

There are many factors that influence the strength of a password and each of those factors used together can help protect your credentials and thus your data. If you're still in doubt over the knowledge your users have around protecting their password and their password strength, then you can always educate them.

  • Show them your password policy and explain to them why it is how it is.
  • Explain to them the pitfalls of clicking on links in emails.
  • Explain installing random software can be invasive and dangerous.
  • Provide links to tools that can help them generate a strong password, or to essays or research papers. Or spend a day writing your own, summarising all the facts important to your business.

This post is designed to be a guide to how to help you decide how to implement safe storage of passwords. It is not meant to be complete one-size-fits-all policy document, though it could be used as a basis for creating a password policy specific to your needs. I've also attempted to give some positive and negative impacts for each area.

Length, or "size is important"

Password length is the most important factor in password strength. Forget entropy, make your password as long as you can. Many policies enforce a minimum length of mixed case, numbers and special characters, and some even impose a maximum length.

The minimum length is important, but please make it longer than 8, which is extremely common. I don't understand why anyone would want to restrict the maximum length of your password. At the end of the day the resultant hash is of a fixed length, so longer user passwords won't have any negative impact on storage concerns. Provide a large characters set from which to chose the password but there is no real need to force a user to use the upper/lower/numeric/special characters.

+ve longer passwords increase complexity, slowing down any brute force attack

-ve the longer the password the more likely it will be to be forgotten by the user resulting in more password resets which could result in more helpdesk calls.
-ve a user not being able to log in at a given time could impact time sensitive sales


Lifetime, or "all change please"

You should impose a maximum lifetime of a password. You could implement expiration such that after a given period of time you prompt the user to change their password. You could do this at login, or you could send them a mail prompting them to change their password, maybe providing a link to the reset page.
It may be worth adding historical knowledge of passwords used. When a user is prompted to change their password according to the lifetime policy the new password should not match any of the previous passwords used for the account. This eliminates the possibility of a stolen password database where the passwords have been expired and thus becoming stale, to then becoming valid again.

+ve any leaked password DB would only have a finite lifetime as the passwords would be stale after a given period of time
+ve informing the user to change their password may increase customer confidence and show you take security seriously.

-ve implementation of an expiration mechanism would have to be coded, which takes time and resource
-ve nagging the user may have a negative impact on user experience


Lockout, or "add some treacle"

It is quite common for hackers to brute force a live system. Obviously you've already implement a set of rules that will alert you to such attempts, along with your detection of cross-site scripting monitoring and alerting. You can take a couple of approaches here. You can lock accounts after a specified number of failed login attempts. Any account that has been locked out would require administrative intervention to re-enable the account.

+ve this will quickly stop any brute force attempts

-ve calls to helpdesk have a cost attributed to them, businesses are in business to make money

An alternative is to add some treacle. After a given number of failed attempts, apply a pause, a delay until the next login attempt can be made.

+ve slows the brute force attempt down


Salting, or "pass the salt"

Appending a salt to the password prior to applying the hash function has the effect of lengthening the password. You should generate a different salt for each password. If you can store the salt in a separate database, then great, that will slow a brute force attempt on a leaked database and storing salts in a different databases reduces the likelihood of the hash and the salt being stolen at the same time. Added the salt slows down the hash brute force, it may even take so long that the password has gone stale by the time it is cracked. There is no harm in rotating salts each time the user logs in. This could be implemented a an asynchronously (thus not affecting the user experience) strengthening the argument for storing the salt in a different database to the hash; if the theft of the two databases is not synchronised, then the hacker doesn't have the expected salt for a given user.  You can always append an additional, option application salt. This adds one more pieces to the puzzle that the attack must solve.  Store this somewhere that the salt, the final hash or the algorithm is not stored, thus requiring the attack to gain access to additional systems.

+ve slows down a brute force attempt


Key strengthening, or "stretch, and relax"

Employ a form of key stretching will strengthen any given password. Key stretching, by design executes slowly; introducing a delay to the hashing process introduces the same delay in the brute forcing process.

+ve hacker needs to know how the algorithm is implemented, and for that they would need access to source code
+ve significantly slows down any brute forcing

-ve slowing down the password verification _could_ impact user experience when logging in
initialise key
loop 100,000
        key = hash(key + password + salt)

Why hash all 3? This reduces the chances of collisions


Cryptographic functions, or "don't make a hash of it"

Choose your hashing function you probably want to use SHA-2, though judging by the rate of hash function breakage, you'll want to ensure you can quickly and easily upgrade to the latest SHA implementation; so prepare for SHA-3.


Complexity indicator, or "a show of strength"

It is always good to give your users a visual indication of how strong their password is. You can add a graphical indicator on the registration page and on password reset page. Though I would not retrospectively send my users an email telling them that they must change their password as it has found to be under strength. This would give the impression that somehow you have visibility of it.


I (don't) want to do whatever common people do

Common passwords have been collated for years. For example, 123456 was the #1 common password for years. There are multiple sources where you can download lists for the top 100, 1,000, 10,000, 100,000 passwords. Use one of these lists to ensure your users don't.


Sensible storage, or "Cover me, I need back up!"

Back up source code which will contain the algorithm, the per password salt, application salt and the resultant hash in isolation. There is no point is keeping them all separate in production if you then back themup to the same location. If you can, encrypt your back up.


Summary

There are many ways to increase the strength of passwords at rest and how you influence and educate your users in choosing strong passwords in the first place. There is no one right way and no one size fits all.
  • Educate your users/customers about secure passwords, they'll thank you for it.
  • Weigh up what is the right solution for your requirements.
  • Leave comments/suggestions/advice below (-;