Secure generation and management of cookies
import play.api.mvc._
object Application extends Controller {
def index = Action {
val cookie = Cookie("sessionId", "user123")
Ok("Welcome!").withCookies(cookie)
}
}
In the above code, we are creating a new cookie with the name
sessionId
and value
user123
. This cookie is then added to the HTTP response using the
withCookies
method.
The vulnerability here is that the cookie is not marked as Secure or HttpOnly.
- The Secure attribute tells the browser to only send the cookie if the request is being sent over a secure channel such as HTTPS. This will help prevent the cookie from being passed over unencrypted requests. If the Secure attribute is not set, then the cookie will be transmitted in clear text if the user visits any HTTP URLs within the cookie's scope. This could make it vulnerable to interception and eavesdropping.
- The HttpOnly attribute is used to help prevent attacks such as cross-site scripting, because it does not allow the cookie to be accessed via a client-side script such as JavaScript. This means that even if a cross-site scripting (XSS) attack is successful, the attacker would not be able to access the cookie.
Not setting these attributes can lead to potential security risks such as disclosure of sensitive information and session hijacking.
import play.api.mvc._
import play.api.libs.crypto.DefaultCookieSigner
object Application extends Controller {
def index = Action {
val sessionId = java.util.UUID.randomUUID().toString // Generate a random session ID
val cookieSigner = new DefaultCookieSigner
val signedSessionId = cookieSigner.sign(sessionId) // Sign the session ID
val cookie = Cookie("sessionId", signedSessionId, httpOnly = true, secure = true, sameSite = Some(Cookie.SameSite.Strict))
Ok("Welcome!").withCookies(cookie)
}
}
The updated code now sets the
secure
flag to
true
when creating the cookie. This ensures that the cookie is only sent over HTTPS, preventing it from being sent in plain text.
The
httpOnly
flag is also set to
true
, which prevents client-side scripts from accessing the cookie. This is a crucial security measure to prevent cross-site scripting (XSS) attacks.
The
SameSite
attribute is set to
Strict
, which means the cookie will only be sent in a first-party context (i.e., if the URL displayed in the address bar is the same as the cookie’s domain). This helps to mitigate cross-site request forgery (CSRF) attacks.
Instead of using a static value ("user123") for the session ID, the code now generates a random and unique session ID using
java.util.UUID.randomUUID().toString
. This makes it much harder for an attacker to guess the session ID and hijack the session.
Finally, the session ID is signed using Play's
DefaultCookieSigner
. This ensures that the session ID cannot be tampered with, as any changes to the session ID will invalidate the signature.