Insecurely generated cookies - HttpOnly
Need
Protection of session cookies from access by client-side scripts
Context
• Usage of Kotlin 1.9+ on the JVM for building web applications
• Usage of the javax.servlet API for cookies
Description
1. Non compliant code
import javax.servlet.http.Cookie
import javax.servlet.http.HttpServletResponse
fun addSessionCookie(response: HttpServletResponse, sessionId: String) {
// Without HttpOnly, any script on the page can read the session id
val cookie = Cookie("SESSIONID", sessionId).apply {
secure = true
path = "/"...The `addSessionCookie` function below creates the cookie that carries the session identifier and marks it `Secure`, but it never calls `isHttpOnly = true`, so the cookie is sent without the `HttpOnly` attribute. Without `HttpOnly`, the browser exposes the cookie to JavaScript through `document.cookie`. Any cross-site scripting flaw in the application, or a compromised third-party script such as an analytics or advertising library, can read the session identifier and send it to an attacker, who then uses it from their own browser to take over the session.
2. Steps
• Set `isHttpOnly = true` on every `Cookie` that carries a session, authentication or CSRF token before calling `addCookie`.
• Configure container-managed session cookies as `HttpOnly`, for example with `server.servlet.session.cookie.http-only=true`.
• Build sensitive cookies in a single helper function so the attributes cannot be forgotten in individual handlers.
• Combine `HttpOnly` with the `Secure` and `SameSite` attributes and with a restrictive Content-Security-Policy.
3. Secure code example
import javax.servlet.http.Cookie
import javax.servlet.http.HttpServletResponse
fun addSessionCookie(response: HttpServletResponse, sessionId: String) {
val cookie = Cookie("SESSIONID", sessionId).apply {
isHttpOnly = true
secure = true
path = "/"...The corrected function sets `isHttpOnly = true` on the cookie, so the browser sends it with each request but refuses to expose it to JavaScript. Scripts injected into the page can no longer read or copy the session identifier. `HttpOnly` does not fix cross-site scripting, since an injected script can still act on behalf of the user while the page is open, but it prevents the theft that would let an attacker keep using the session from elsewhere. The cookie remains `Secure`, so it is only sent over HTTPS. For container-managed sessions, the same attributes are configured once, for example with `server.servlet.session.cookie.http-only=true` in Spring Boot.
References
• 128. Insecurely generated cookies - HttpOnly