Tuesday, June 12, 2012

Top 7 Programmers bad habits

1. The All code is crap, except mine, attitude.

I have bad news for you buddy, all code is crap. No matter how much effort you put on it, there is always a majority of programmers who are going to think that your code sucks and that they could have done it 10 times better. I have already covered this topic in previous posts, you can find more information of what exactly I mean when I say that all the code is crap here and here.

How to fix it : Don’t criticise others people code, it could be yours the one in the spotlight, try to make objective and professional observations instead, but don’t judge. Be humble and try to learn from everyone around you, hopefully then your code won’t be so bad.

2. The “I fix that in a second” catastrophe.

Taking shortcuts is very tempting, everyone has done it. There are actually situations where they are necessary, but in overall, they are dangerous, very dangerous and should be avoided. A shortcut which goes wrong may save you a few hours, but may cause months of pain.

How to fix it : Don’t trust yourself when carrying delicate activities. Ask someone else to review what you are doing. Make sure that if you are about to take a shortcut, you make very clear to the stakeholders what the reasons and the risks are. Try to get a manager to sign off every time you are about to take a shortcut.

3. The “That will only take a second” misconception.

Being Barcelona my favourite city, I am very proud of the Sagrada Familia Cathedral, which is very well know for its beautiness, and also for the time is estimated it will take to complete, (in construction since 1882), but that’s probably because they didn’t ask a programmer to estimate, otherwise the estimate would probably have been somewhere around 2 weeks.

How to fix it : For starters, is important to understand that accurate estimations in software development for non trivial solutions are impossible, we can only guess. Also remember that is very likely that you will find so many things which you didn’t foresee when you start developing that is worth multiplying the estimate to cover for those, I usually go with 1.5 or 2.

4. The ego spiral

Many programmers discussions look more like rooster fights than human discussions. This usually happens in design and architectural meetings. It is actually quite easy to detect this ego spirals, you just have to substitute most of what the contenders are saying with COC! COC! COCOCOOCCC! COOC!

How to fix it: Leave your ego at home. Big egos are one of the biggest non technical issues for any programmer. Keep in mind some basic considerations when making decisions.

5. “It wasn’t me!”

In my opinion, other bad habit from most programmers is the lack of accountability. We always have an excuse… It’s like if we were saying that under normal conditions we would never make a mistake, which honestly is quite hard to believe.

How to fix it: No need to cry, or to perform seppuku, (aka harakiri), when we make a mistake. Having a healthy attitude where we can you just say something like: “yeah, sorry, now we need to do this to fix this issue, my fault” is a very professional attitude, and it will help you to build a reputation and to be better considered by your colleagues.

6. The demotivated genius.

Repetitive and simple tasks are not the best motivators, but they need to be done, programmers tend to get demotivated and very unproductive when they need to complete them.

How to fix it: Discipline. Unfortunately, there isn’t any other remedy I can think of.

7. The premature programmer.

If programming was sex, there would be a lot of unsatisfied computers. You can just not go in, do things halfway through and then fall sleep. One of the concepts that I find most programmers struggling with is the concept of “Done”. Remember that done means: tested (and not only unit tested), documented, committed, merged…

How to fix it: This one is tricky, the complexity of non apparent necessary tasks to fully complete some functionality is quite high and usually requires discipline and training. Probably the two easiest ways to help a programmer understand if some code is done are peer reviews and demos.


Reference: Top 7 Programmers bad habits from our JCG partner Rajith Delantha at the Looping around with Rajith... blog.

Secure Password Storage - Don'ts, dos and a Java example

The importance of storing passwords securely
As software developers, one of our most important responsibilities is the protection of our users' personal information. Without technical knowledge of our applications, users have no choice but to trust that we're fulfilling this responsibility. Sadly, when it comes to passwords, the software development community has a spotty track record.
While it's impossible to build a 100% secure system, there are fortunately some simple steps we can take to make our users' passwords safe enough to send would-be hackers in search of easier prey.
If you don't want all the background, feel free to skip to the Java SE example below.
The Don'ts
First, let's quickly discuss some of the things you shouldn't do when building an application that requires authentication:
  • Don't store authentication data unless you really have to. This may seem like a cop-out, but before you start building a database of user credentials, consider letting someone else handle it. If you're building a public application, consider using OAuth providers such as Google or Facebook. If you're building an internal enterprise application, consider using any internal authentication services that may already exist, like a corporate LDAP or Kerberos service. Whether it's a public or internal application, your users will appreciate not needing to remember another user ID and password, and it's one less database out there for hackers to attack.
  • If you must store authentication data, for Gosling's sake don't store the passwords in clear text. This should be obvious, but it bears mentioning. Let's at least make the hackers break a sweat.
  • Don't use two-way encryption unless you really need to retrieve the clear-text password. You only need to know their clear-text password if you are using their credentials to interact with an external system on their behalf. Even then, you're better off having the user authenticate with that system directly. To be clear, you do not need to use the user's original clear-text password to perform authentication in your application. I'll go into more detail on this later, but when performing authentication, you will be applying an encryption algorithm to the password the user entered and comparing it to the encrypted password you've stored.
  • Don't use outdated hashing algorithms like MD5. Honestly, hashing a password with MD5 is virtually useless. Here's an MD5-hashed password: 569a70c2ccd0ac41c9d1637afe8cd932. Go to http://www.md5hacker.com/ and you can decrypt it in seconds.
  • Don't come up with your own encryption scheme. There are a handful of brilliant encryption experts in the world that are capable of outwitting hackers and devising a new encryption algorithm. I am not one of them, and most likely, neither are you. If a hacker gets access to your user database, they can probably get your code too. Unless you've invented the next great successor to PBKDF2 or bcrypt, they will be cackling maniacally as they quickly crack all your users' passwords and publish them on the darknet.
The Dos
Okay, enough lecturing on what not to do. Here are the things you need to focus on:
  • Choose a one-way encryption algorithm. As I mentioned above, once you've encrypted and stored a user's password, you never need to know the real value again. When a user attempts to authenticate, you'll just apply the same algorithm to the password they entered, and compare that to the encrypted password that you stored.
  • Make the encryption as slow as your application can tolerate. Any modern password encryption algorithm should allow you to provide parameters that increase the time needed to encrypt a password (i.e. in PBKDF2, specifying the number of iterations). Why is slow good? Your users won't notice if it takes an extra 100ms to encrypt their password, but a hacker trying a brute-force attack will notice the difference as they run the algorithm billions of times.
  • Pick a well-known algorithm. The National Institute of Standards and Technology (NIST) recommends PBKDF2 for passwords. bcrypt is a popular and established alternative, and scrypt is a relatively new algorithm that has been well-received. All these are popular for a reason: they're good.
PBKDF2
Before I give show you some concrete code, let's talk a little about why PBKDF2 is a good choice for encrypting passwords:
  • Recommended by the NIST. Section 5.3 of Special Publication 800-132 recommends PBKDF2 for encrypting passwords. Security officials will love that.
  • Adjustable key stretching to defeat brute force attacks. The basic idea of key stretching is that after you apply your hashing algorithm to the password, you then continue to apply the same algorithm to the result many times (the iteration count). If hackers are trying to crack your passwords, this greatly increases the time it takes to try the billions of possible passwords. As mentioned previously, the slower, the better. PBKDF2 lets you specify the number of iterations to apply, allowing you to make it as slow as you like.
  • A required salt to defeat rainbow table attacks and prevent collisions with other users. A salt is a randomly generated sequence of bits that is unique to each user and is added to the user's password as part of the hashing. This prevents rainbow table attacks by making a precomputed list of results unfeasible. And since each user gets their own salt, even if two users have the same password, the encrypted values will be different. There is a lot of conflicting information out there on whether the salts should be stored someplace separate from the encrypted passwords. Since the key stretching in PBKDF2 already protects us from brute-force attacks, I feel it is unnecessary to try to hide the salt. Section 3.1 of NIST SP 800-132 also defines salt as a "non-secret binary value," so that's what I go with.
  • Part of Java SE 6. No additional libraries necessary. This is particularly attractive to those working in environments with restrictive open-source policies.
Finally, a concrete example
Okay, here's some code to encrypt passwords using PBKDF2. Only Java SE 6 is required.
01import java.security.NoSuchAlgorithmException;
02import java.security.SecureRandom;
03import java.security.spec.InvalidKeySpecException;
04import java.security.spec.KeySpec;
05import java.util.Arrays;
06 
07import javax.crypto.SecretKeyFactory;
08import javax.crypto.spec.PBEKeySpec;
09 
10public class PasswordEncryptionService {
11 
12 public boolean authenticate(String attemptedPassword, byte[] encryptedPassword, byte[] salt)
13   throws NoSuchAlgorithmException, InvalidKeySpecException {
14  // Encrypt the clear-text password using the same salt that was used to
15  // encrypt the original password
16  byte[] encryptedAttemptedPassword = getEncryptedPassword(attemptedPassword, salt);
17 
18  // Authentication succeeds if encrypted password that the user entered
19  // is equal to the stored hash
20  return Arrays.equals(encryptedPassword, encryptedAttemptedPassword);
21 }
22 
23 public byte[] getEncryptedPassword(String password, byte[] salt)
24   throws NoSuchAlgorithmException, InvalidKeySpecException {
25  // PBKDF2 with SHA-1 as the hashing algorithm. Note that the NIST
26  // specifically names SHA-1 as an acceptable hashing algorithm for PBKDF2
27  String algorithm = "PBKDF2WithHmacSHA1";
28  // SHA-1 generates 160 bit hashes, so that's what makes sense here
29  int derivedKeyLength = 160;
30  // Pick an iteration count that works for you. The NIST recommends at
31  // least 1,000 iterations:
33  // iOS 4.x reportedly uses 10,000:
35  int iterations = 20000;
36 
37  KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations, derivedKeyLength);
38 
39  SecretKeyFactory f = SecretKeyFactory.getInstance(algorithm);
40 
41  return f.generateSecret(spec).getEncoded();
42 }
43 
44 public byte[] generateSalt() throws NoSuchAlgorithmException {
45  // VERY important to use SecureRandom instead of just Random
46  SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
47 
48  // Generate a 8 byte (64 bit) salt as recommended by RSA PKCS5
49  byte[] salt = new byte[8];
50  random.nextBytes(salt);
51 
52  return salt;
53 }
54}
The flow goes something like this:
  1. When adding a new user, call generateSalt(), then getEncryptedPassword(), and store both the encrypted password and the salt. Do not store the clear-text password. Don't worry about keeping the salt in a separate table or location from the encrypted password; as discussed above, the salt is non-secret.
  2. When authenticating a user, retrieve the previously encrypted password and salt from the database, then send those and the clear-text password they entered to authenticate(). If it returns true, authentication succeeded.
  3. When a user changes their password, it's safe to reuse their old salt; you can just call getEncryptedPassword() with the old salt.
Easy enough, right? If you're building or maintaining an application that violates any of the "don'ts" above, then please do your users a favor and use something like PBKDF2 or bcrypt. Help them, Obi-Wan Developer, you're their only hope.