Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added a CS, need to test it. Changed NCE a bit more

...

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())) {
        // set error and return
      } else {
        // forward to welcome page
      }
    } else {
        boolean validated = loginService.isUserValid(username, password);
   
    
        if (validated) {
          Cookie loginCookie = new Cookie("credentialsrememberme", username + ";"
  	                           + ";" + password.toString());
          response.addCookie(loginCookie);
          // ... forward to welcome page
        } else {
          // set error and return
        }
     }
   } else { // no remember me functionality selected
      // ... proceed with regular authentication, if it fails set error and return
   }
    
  Arrays.fill(password, ' ');
}

...

Compliant Solution (Session)

This compliant solution stores user information using the HttpSesssion class within the javax.servlet.http package. Because HttpSession objects are server-side, an attacker cannot use XSS or man-in-the-middle attacks to gain direct access to the session information. Rather, the cookie stores a session ID that refers to the user's HttpSession object stored on the server. Consequently, the attacker cannot gain access to the user's account details without first gaining access to the session ID.implements the remember me functionality by storing the username and a secure random string in the cookie. It also maintains state in the session using HttpSession.

Code Block
bgColor#ccccff
public class InsecureServlet extends HttpServletprotected void doPost(HttpServletRequest request,
  HttpServletResponse response) {
  private UserDAO userDAO;

  // ...

  private String login(HttpServletRequest request) {validate input (omitted)
  String username List<String> errors = new ArrayList<String>(request.getParameter("username");
  char[] password = request.setAttributegetParameter("errors", errorspassword").toCharArray();

  boolean rememberMe String username = Boolean.valueOf(request.getParameter("usernamerememberme"));
  LoginService loginService char[]= password = request.getParameter("password").toCharArraynew LoginServiceImpl();
    boolean validated = false;
    // Basic input validation
if (rememberMe) {
      if (!usernamerequest.matchesgetCookies(")[\\w]*") || !password.toString().matches("[\\w]*")) {0] != null
          && request.getCookies()[0].getValue() != null) {
                
      errors.add("Incorrect user nameString[] orvalue password format."= request.getCookies()[0].getValue().split(";");
        String return "error.jsp"randomFromCookie = value[1];
     }

   
		if (!loginService.mappingExists(username, randomFromCookie)) {
      UserBean    dbUservalidated = thisloginService.userDAO.lookupisUserValid(username, password);
          
          if (!dbUser.checkPassword(password)validated) {
      errors.add("Passwords do not match.");       // set error and return
      return "error.jsp";    }
        }
        
     HttpSessionString sessionnewRandom = requestloginService.getSessiongetRandomString();
     // Invalidatereset the oldrandom sessionevery idtime
     sessionloginService.invalidatemapUserForRememberMe(username, newRandom);
     HttpSession session = request.getSession();
  // Generate new session id
.invalidate();
     session = request.getSession(true);
     // Set session timeout to one hour
     session.setMaxInactiveInterval(60 * 60);
     // Store user bean within the session attribute and a random attribute in session scope
     session.setAttribute("user", dbUserloginService.getUsername());
     Cookie loginCookie = new Cookie("rememberme", username + ";"
                                      + newRandom);
     response.addCookie(loginCookie);
     // ... forward to welcome page
   } else {
     // Clear password char array ...authenticate using isUserValid() and if failed, set error
   }
    Arrays.fill(password, ' ');

    return "welcome.jsp";
  }
}
}

A mapping table is maintained at server side. The table contains username and secure random string pairs. When a user selects "remember me", the doPost() method checks whether the supplied cookie contains a valid username and random string pair. If the mapping contains a matching pair, the user is authenticated and forwarded to the welcome page. If not, then an error is returned to the client. If the user selects "remember me" but the client does not supply a valid cookie, the user is made to authenticate using his credentials. If the authentication is successful, a new cookie is issued with "remember me" characteristics.

This solution also avoids session fixation attacks by This solution avoids session fixation attacks [OWASP 2009] by invalidating the current session and creating a new session. It also reduces the window in which an attacker could perform a session hijacking attack by setting the session timeout to one.

...