Securely generate session tokens with appropriate lifespan
import play.api.mvc._
import java.util.Date
class SessionController extends Controller {
def createSession = Action { request =>
val token = java.util.UUID.randomUUID().toString
val expiryDate = new Date(System.currentTimeMillis() + 5 * 24 * 60 * 60 * 1000)
Ok("Session Created").withSession("token" -> token, "expiryDate" -> expiryDate.toString)
}
}
In the above code, the
createSession
method in
SessionController
class is responsible for creating a new session. It generates a random session token using
java.util.UUID.randomUUID().toString
and sets an expiry date for the token as current time plus 5 days (5*24*60*60*1000 milliseconds).
The session is then created with these token and expiry date using
Ok("Session Created").withSession("token" -> token, "expiryDate" -> expiryDate.toString)
.
The vulnerability here is that the session token has a long lifespan of approximately 5 days. If an attacker is able to get hold of the session token, they can use it to impersonate the user for up to 5 days. This could lead to unauthorized access and potential data breaches.
A more secure approach would be to reduce the lifespan of the session token and implement mechanisms to invalidate the token after a certain period of inactivity.
import play.api.mvc._
import java.util.UUID
import java.security.SecureRandom
import java.time.Instant
import java.time.temporal.ChronoUnit
class SessionController extends Controller {
private val secureRandom = new SecureRandom()
def createSession = Action { request =>
val token = new UUID(secureRandom.nextLong(), secureRandom.nextLong()).toString
val expiryDate = Instant.now().plus(30, ChronoUnit.MINUTES)
Ok("Session Created").withSession("token" -> token, "expiryDate" -> expiryDate.toString)
}
def checkSession = Action { request =>
request.session.get("expiryDate") match {
case Some(date) =>
if (Instant.parse(date).isBefore(Instant.now())) {
Unauthorized("Session Expired")
} else {
Ok("Session Valid")
}
case None => Unauthorized("No Session")
}
}
}
The updated code now uses a
SecureRandom
instance to generate session tokens, which are more secure than the previously used
UUID.randomUUID()
. The
SecureRandom
class provides a cryptographically strong random number generator.
The expiration time of the session tokens has been reduced from 5 days to 30 minutes. This is done by using
Instant.now().plus(30, ChronoUnit.MINUTES)
. This reduces the window of opportunity for an attacker to use a stolen session token.
A new method
checkSession
has been added. This method checks if the session token has expired by comparing the stored expiry date with the current time. If the session token has expired, it returns an "Unauthorized" response. If the session token is valid, it returns an "Ok" response. If no session token is found, it also returns an "Unauthorized" response. This ensures that expired session tokens are invalidated and cannot be used.