Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring security authentication management vulnerability

Spring documentation says that remember me is implemented by storing following information in cookie -

base64(username + ":" + expirationTime + ":" + md5Hex(username + ":" + expirationTime + ":" password + ":" + key))

I have following confusions -

  1. Why use an unsecure hash like MD5 to digest the information instead of using SHA-1 or SHA-2. Would the performance hit from these be significant for such a small piece of information?

  2. Why transmit this information over the network at all? Why not maintain a map of cryptographically secure random number and this info on the server, returning only the map key as a cookie. AFAIK this is the approach used by Servlet API and is deemed more secure.

like image 662
Kshitiz Sharma Avatar asked Apr 20 '12 05:04

Kshitiz Sharma


1 Answers

Lets begin with the second question because it is the more relevant one:

second question "Why transmit the password over the network at all...." answer:

Because what you described is only the Simple Hash-Based Token Approach

If you scroll down the page Spring Security Reference: Chapter 10 Remember-Me Authentication you will see that spring security can also use a different remember me approaches: Chapter 10.3 Persistent Token Approach. And this is what you suggested in your second question.


first question: Short answer to "Would the performance hit from these be significant for such a small piece of information?" - No

So if you want to use the Simple Hash-Based Token Approach and feel that MD5 is to unsecured, then you can subclass TokenBasedRememberMeService [javadoc] and override the String makeTokenSignature(long tokenExpiryTime, String username, String password) method. For example (untested)

protected String makeTokenSignature(long tokenExpiryTime, String username, String password) {
    String data = username + ":" + tokenExpiryTime + ":" + password + ":" + getKey();
    MessageDigest digest;
    try {
        digest = MessageDigest.getInstance("SHA-256");
    } catch (NoSuchAlgorithmException e) {
        throw new IllegalStateException("No SHA-256 algorithm available!");
    }

    return new String(Hex.encode(digest.digest(data.getBytes())));
}
like image 144
Ralph Avatar answered Nov 04 '22 01:11

Ralph