The first rule of building your own password storage mechanisms is don’t. Like most other highly-specialized wheels, you aren’t going to do as good a job as someone who specializes in it. It’s bad enough when you write your own date mangling code, but for security-critical features, like passwords or encryption, you’re begging for trouble.

Joni spotted some trouble: many of the users in the database had the same password hash. This, of course, should never happen- the password should be combined with a user-specific salt as part of the hashing, so that even if two users had the same password, they’d have different hashes.

Joni investigated, and found the code used:

string EncodePassword(string pass, int passwordFormat, string salt)
{
    if (passwordFormat == 0) // MembershipPasswordFormat.Clear
        return pass;

    //byte[] bIn = Encoding.Unicode.GetBytes(pass);
    byte[] bIn = UTF8Encoding.UTF8.GetBytes(pass);
    byte[] bSalt = Convert.FromBase64String(salt);
    byte[] bAll = new byte[bSalt.Length + bIn.Length];
    byte[] bRet = null;

    Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length);
    Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length);
    if (passwordFormat == 1)
    { // MembershipPasswordFormat.Hashed
        HashAlgorithm s = HashAlgorithm.Create(Membership.HashAlgorithmType);
        //bRet = s.ComputeHash(bAll);
        bRet = s.ComputeHash(bIn);
    }
    else
    {
        bRet = EncryptPassword(bAll);
    }

    return Convert.ToBase64String(bRet);
}

Note the Buffer.BlockCopy lines. As you can see, the code does all the important heavy-lifting to prepend the salt to the password… and then it ignores that work and just stores the hash of bIn- the original password as a byte array. There is also a hint, from the comments, that they avoided using clearly-named enums and instead used integers… but kept the enums in the comments, for readability!

TRWTF is that this is the initial commit of this code into source control, so there’s no explanation for this.

[Advertisement] Infrastructure as Code built from the start with first-class Windows functionality and an intuitive, visual user interface. Download Otter today!