Want to protect your cookie? Well, not from Santa Claus. I'm talking about HTTP Cookie. Using the HttpOnly flag when generating a cookie helps mitigate the risk of a client side script accessing the protected cookie. In other words, it won't be accessible programmatically on the client side (e.g. JavaScript). The cookie will be driven by the backend.
Why do this? To mitigate cross-site scripting (XSS) attacks. If a cross-site scripting flaw exists, and a user accidentally accesses a link that exploits this flaw, the browser will not reveal the cookie to a third party. Currently, every major browser supports HttpOnly cookies. If a browser does not support HttpOnly and a website attempts to set an HttpOnly cookie, the HttpOnly flag will be ignored by the browser, thus creating a traditional, script accessible cookie. As a result, the cookie (typically your session cookie) becomes vulnerable to theft or modification by a malicious script. Majority of XSS attacks target theft of session cookies. A server could help mitigate this issue by setting the HttpOnly flag on a cookie it creates, indicating the cookie should not be accessible on the client. If a browser that supports HttpOnly detects a cookie containing the HttpOnly flag, and client side script code attempts to read the cookie, the browser returns an empty string as the result. This causes the attack to fail by preventing the malicious (usually XSS) code from sending the data to an attacker’s website.
Demonstration
Before we begin, these are the tools I used to make this example:
- IntelliJ IDEA 2023.3.4 (Community Edition)
- openjdk-17.0.10
- Spring Boot v3.4.1
- Windows 11
The example code is here, github.com/jpllosa/httponly-cookie. Download it as you please. Now, on with the show. Run the Spring Boot app. Go to the login page, you should see something like below. Please forgive the look, this demo is about HttpOnly and not about the UI.
Without HttpOnly
Log in. Just type any user name and password. You should have something like below. Open Web Tools and head over to the Storage tab (it could be called a different name on a different browser). Take note of the HttpOnly column of the cookie named MY_SESS.
This is the code of the Controller serving the page. Take note that we have commented out the line that sets the HttpOnly flag.
package com.blogspot.jpllosa.httponly_cookie;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.CookieValue;
@Controller
public class LoginController {
@GetMapping("/login")
public String getLogin() {
return "login";
}
@PostMapping("/login")
public String postLogin(
@RequestParam(name="username", required=true) String username,
@RequestParam(name="password", required=true) String password,
HttpServletResponse response,
HttpSession session) {
session.setAttribute("username", username);
session.setAttribute("password", password);
Cookie cookie = new Cookie("MY_SESSION", "supercalifragilisticexpialidocious");
// cookie.setHttpOnly(true);
response.addCookie(cookie);
return "redirect:/welcome";
}
@GetMapping("/welcome")
public String welcomeUser(
@CookieValue(value = "MY_SESSION") String mySession,
Model model,
HttpSession session) {
model.addAttribute("username", session.getAttribute("username"));
model.addAttribute("password", session.getAttribute("password"));
model.addAttribute("mySession", mySession);
return "welcome";
}
}
Now, click "Clear MY_SESSION" button. Notice that the cookie is gone as below.
With HttpOnly
Alright, this time, we'll put in the HttpOnly flag. Uncomment cookie.setHttpOnly(true);
and restart the Spring Boot app. Log in again and as usual, have the Storage tab open. What happens when you click the "Clear MY_SESSION" button now? It's still there no matter how many times we click the button as shown on the console logs.
Spring Boot HttpOnly Cookie Conclusion
There you have it. A nice way of protecting your cookie. Having the HttpOnly flag set prevents thrid parties from accessing you very important cookie. It's now the task of the backend to manage the cookie. Thank you for reading.