Skip to main content

Insecure session management

Need

Secure session management

Context

  • Usage of Go 1.16 for building high-performance and concurrent applications
  • Usage of gin-gonic/gin for building web applications in Go
  • Usage of sessions package from github.com/gin-contrib for managing user sessions in a Gin web framework

Description

Non compliant code

package main

import (
"github.com/gin-gonic/gin"
"github.com/gin-contrib/sessions"
)

func main() {
r := gin.Default()
store := sessions.NewCookieStore([]byte("secret"))
r.Use(sessions.Sessions("mysession", store))

r.GET("/login", func(c *gin.Context) {
session := sessions.Default(c)
session.Set("user", "john")
session.Save()
})

r.GET("/logout", func(c *gin.Context) {
session := sessions.Default(c)
session.Clear()
session.Save()
})

r.Run(":8080")
}

This code snippet is a simple implementation of session management in a Go backend application using the Gin framework and the gin-contrib/sessions package.

The "/login" route creates a new session and assigns a user to it. The "/logout" route is intended to clear the session data, effectively logging the user out.

The vulnerability lies in the "/logout" route. Although it clears the session data, it does not invalidate the session itself. This means that even after a user has "logged out", the session token is still valid and can be used to make requests.

This is a security risk as an attacker could potentially obtain a valid session token (for example, through session sidejacking) and use it to impersonate the user, even after the user has logged out.

To fix this vulnerability, the server should invalidate the session token when the user logs out. This can be achieved by using the session.Clear() and session.Save() methods to clear the session data and then save the session, and then by using the session.Options(sessions.Options{MaxAge: -1}) method to set the session's maximum age to -1, effectively expiring the session immediately.

Steps

  • Set an expiration time for the session token.
  • Invalidate the session token when the user logs out.
  • Implement a mechanism to check the validity of the session token before processing requests.
  • Use secure session storage mechanisms, such as encrypted cookies or server-side session storage.
  • Regularly rotate the session token to minimize the risk of session hijacking.

Compliant code

package main

import (
"github.com/gin-gonic/gin"
"github.com/gin-contrib/sessions"
"time"
)

func main() {
r := gin.Default()
store := sessions.NewCookieStore([]byte("secret"))
store.Options(sessions.Options{MaxAge: int(30 * time.Minute), Path: "/", HttpOnly: true, Secure: true}) // Set session options
r.Use(sessions.Sessions("mysession", store))

r.GET("/login", func(c *gin.Context) {
session := sessions.Default(c)
session.Set("user", "john")
session.Save()
})

r.GET("/logout", func(c *gin.Context) {
session := sessions.Default(c)
session.Clear()
session.Save()
})

r.Run(":8080")
}

The updated code now includes a secure session management mechanism. Here's how it works:

  1. Set an expiration time for the session token: The MaxAge option is set to 30 minutes. This means that the session token will automatically expire after 30 minutes of inactivity. This reduces the risk of session hijacking.

  2. Invalidate the session token when the user logs out: The Clear() function is called when the user logs out. This function removes all data associated with the current session, effectively invalidating the session token.

  3. Use secure session storage mechanisms: The HttpOnly and Secure options are set to true. This means that the session cookie can only be accessed through HTTP requests (not through client-side scripts), and it will only be sent over secure (HTTPS) connections. This helps to prevent session hijacking and session sidejacking attacks.

  4. Regularly rotate the session token: Although not shown in the code, it's recommended to regularly rotate the session token. This can be done by generating a new session token at regular intervals or after certain events (e.g., when the user logs in, changes their password, etc.). This helps to minimize the risk of session hijacking.

By implementing these measures, the application now has a secure session management mechanism that helps to protect against common session-related attacks.

References