Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

In this noncompliant code example, the login servlet stores the user name and password in the cookie to identify the user for subsequent requests.:

Code Block
bgColor#FFcccc
protected void doPost(HttpServletRequest request,
  HttpServletResponse response) {
  
  String username = request.getParameter("username");
  char[] password = request.getParameter("password").toCharArray();
  boolean rememberMe = Boolean.valueOf(request.getParameter("rememberme"));
  
  LoginService loginService = new LoginServiceImpl();
        
  if (rememberMe) {
    if (request.getCookies()[0] != null && request.getCookies()[0].getValue() != null) {
      String[] value = request.getCookies()[0].getValue().split(";");
      
      if (!loginService.isUserValid(value[0], value[1].toCharArray())) {
        // setSet error and return
      } else {
        // forwardForward to welcome page
      }
    } else {
        boolean validated = loginService.isUserValid(username, password);
      
        if (validated) {
          Cookie loginCookie = new Cookie("rememberme", username
                             + ";" + new String(password));
          response.addCookie(loginCookie);
          // ... forward to welcome page
        } else {
          // setSet error and return
        }
     }
   } else { // noNo remember -me functionality selected
      // proceedProceed with regular authentication, if it fails set error and return
   }
    
  Arrays.fill(password, ' ');
}

However, the attempt to implement the " remember-me " functionality is insecure because sensitive information should not be stored at client-side without strong encryption.  This This code also violates the guideline  MSC66-JG. Store passwords using a hash function.

...

This compliant solution implements the " remember-me " functionality by storing the username user name and a secure random string in the cookie. It also maintains state in the session using HttpSession.:

Code Block
bgColor#ccccff
protected void doPost(HttpServletRequest request,
  HttpServletResponse response) {
  
  // validateValidate input (omitted)
  String username = request.getParameter("username");
  char[] password = request.getParameter("password").toCharArray();
  boolean rememberMe = Boolean.valueOf(request.getParameter("rememberme"));
  LoginService loginService = new LoginServiceImpl();
    boolean validated = false;
    if (rememberMe) {
      if (request.getCookies()[0] != null
          && request.getCookies()[0].getValue() != null) {
                             
        String[] value = request.getCookies()[0].getValue().split(";");
             
        if(value.length != 2) {
          // setSet error and return
        }
             
        if (!loginService.mappingExists(value[0], value[1])) { // (username, random)
          // setSet error and return
        }
      } else {
        validated = loginService.isUserValid(username, password);
                       
        if (!validated) {
          // setSet error and return
        }
      }
        
     String newRandom = loginService.getRandomString();
     // resetReset the random every time
     loginService.mapUserForRememberMe(username, newRandom);
     HttpSession session = request.getSession();
     session.invalidate();
     session = request.getSession(true);
     // Set session timeout to one hour
     session.setMaxInactiveInterval(60 * 60);
     // Store user attribute and a random attribute in session scope
     session.setAttribute("user", loginService.getUsername());
     Cookie loginCookie = new Cookie("rememberme", username + ";"
                                      + newRandom);
     response.addCookie(loginCookie);
     // ... forward to welcome page
   } else {
     // ... authenticate using isUserValid() and if failed, set error
   }
    Arrays.fill(password, ' ');
}

The server maintains a mapping table that contains username user name and secure random string pairs. When a user selects "remember Remember me," , the doPost() method checks whether the supplied cookie contains a valid username user name and random string pair. If the mapping contains a matching pair, the server authenticates the user and forwarded forwards him or her to the welcome page. If not, the server returns an error to the client. If the user selects "remember Remember me" but the client fails to supply a valid cookie, the server requires the user to authenticate using his or her credentials. If the authentication is successful, the server issues a new cookie with " remember-me " characteristics.

This solution avoids session-fixation attacks by invalidating the current session and creating a new session. It also reduces the window in during which an attacker could perform a session-hijacking attack by setting the session timeout to one1.

Applicability

Violation of this rule places sensitive information within cookies, making the information vulnerable to packet sniffing or XSS attacks.

Related Guidelines

...

[MITRE CWE]

...

Bibliography

...