Insecure session expiration time - Go

Insecure session expiration time - Go

Need

Enforce secure session expiration time

Context

  • Usage of Go 1.16 for building efficient and scalable applications
  • Usage of 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 application
  • Usage of cookie-based sessions with the GitHub.com/gin-contrib/sessions/cookie package

Description

Non compliant code

        package main

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

func main() {
    router := gin.Default()

    store := cookie.NewStore([]byte("secret"))
    router.Use(sessions.Sessions("mysession", store))

    router.GET("/home", func(c *gin.Context) {
        session := sessions.Default(c)
        user := session.Get("user")
        if user == nil {
            c.JSON(401, gin.H{"error": "Unauthorized"})
            return
        }
        c.JSON(200, gin.H{"welcome": user})
    })

    router.Run(":8080")
}
        
        

In the above code, we are using Gin framework for our Go backend application. We are also using gin-contrib/sessions for session management. The session store is created with cookie.NewStore([]byte("secret")) and is used in the router with router.Use(sessions.Sessions("mysession", store)).

In the /home route, we are getting the session and the user from the session. If the user is not in the session, we return a 401 Unauthorized error. If the user is in the session, we return a welcome message.

The vulnerability in this code is that the user sessions do not expire after 5 minutes of inactivity. This means that if a user logs in and then leaves their computer without logging out, anyone can use their session to access the /home route. This is a security risk because it allows unauthorized access to user data.

Steps

  • Set a proper session expiration time for user sessions.
  • Implement a mechanism to track user activity and update the session expiration time accordingly.
  • Use a secure session store to store session data.
  • Encrypt the session data to prevent tampering.
  • Implement proper authentication and authorization mechanisms to ensure only authenticated users can access sensitive routes.
  • Regularly review and update the application's security measures to address any new vulnerabilities.

Compliant code

        package main

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

func main() {
    router := gin.Default()

    store := cookie.NewStore([]byte("secret"))
    store.Options(sessions.Options{MaxAge: int(5 * time.Minute / time.Second)}) // Set session expiration time to 5 minutes
    router.Use(sessions.Sessions("mysession", store))

    router.GET("/home", func(c *gin.Context) {
        session := sessions.Default(c)
        user := session.Get("user")
        if user == nil {
            c.JSON(401, gin.H{"error": "Unauthorized"})
            return
        }
        c.JSON(200, gin.H{"welcome": user})
    })

    router.Run(":8080")
}
        
        

The updated code now includes a session expiration time of 5 minutes. This is achieved by setting the MaxAge option of the session store to 5 minutes. The MaxAge option is set in seconds, so we convert 5 minutes to seconds using time.Minute / time.Second.

This ensures that user sessions will automatically expire after 5 minutes of inactivity, enhancing the security of the application by reducing the window of opportunity for unauthorized access.

Please note that this is a basic implementation and might need to be adjusted based on your specific requirements. For example, you might want to implement a mechanism to extend the session if the user is actively interacting with the application.

Also, remember to replace "secret" with a strong, unique key to ensure the security of your session data.

References