...
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 | ||
---|---|---|
| ||
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)
- TODO - I need to re-do this test the CS Dhruv Mohindra
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 | ||
---|---|---|
| ||
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.
...