...
For web applications, the most common mitigation to this problem is to provide the client with a cookie and store the sensitive information on the server. Cookies are created by a web server and are stored for a period of time on the client. When the client re-connects reconnects to the server, it provides the cookie, which identifies the client to the server, and the server then provides the sensitive information.
...
Code Block | ||
---|---|---|
| ||
protected void doPost(HttpServletRequest request, HttpServletResponse response) { // Validate input (omitted) 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("rememberme", username + ";" + new String(password)); response.addCookie(loginCookie); // ... forwardForward 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, ' '); } |
...
Code Block | ||
---|---|---|
| ||
protected void doPost(HttpServletRequest request, HttpServletResponse response) { // Validate 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) { // Set error and return } if (!loginService.mappingExists(value[0], value[1])) { // (username, random) pair is checked // Set error and return } } else { validated = loginService.isUserValid(username, password); if if (!validated) { // Set error and return } } String newRandom = loginService.getRandomString(); // Reset the random every time loginService.mapUserForRememberMe(username, newRandom); HttpSession session = request.getSession(); session.invalidate(); session = request.getSession(true); // Set session timeout to fifteen15 minutes session.setMaxInactiveInterval(60 * 15); // 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); // ... forwardForward to welcome page } else { // No remember-me functionality selected // ... authenticateAuthenticate using isUserValid() and if failed, set error } Arrays.fill(password, ' '); } |
...
This solution avoids session-fixation attacks by invalidating the current session and creating a new session. It also reduces the window during which an attacker could perform a session-hijacking attack by setting the session timeout to fifteen 15 minutes between client accesses.
...
Storing unencrypted sensitive information on the client makes this information available to anyone who can attack the client.
Bibliography
...