Skip to main content

Sensitive information sent via URL parameters - Session

Need

Secure transmission of sensitive information in session tokens

Context

  • Usage of Go 1.16 for building high-performance and concurrent applications
  • Usage of Gin framework for building web applications in Go

Description

Non compliant code

package main

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

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

r.GET("/session/:token", func(c *gin.Context) {
token := c.Param("token")
// process the token
c.String(200, "Token: %s", token)
})

r.Run() // listen and serve on 0.0.0.0:8080
}

In this example, we have a Go application using the Gin framework. It includes an endpoint for a session which receives a JWT token as a URL parameter.

This is vulnerable because the token is passed in the URL. This means it could be stored in the browser's history, server logs, or other places where URLs are stored. If an attacker gains access to any of these locations, they could potentially retrieve the token and use it to impersonate a legitimate user's session.

Furthermore, if the connection is not secured with HTTPS, the token could be intercepted during transmission. This is known as a Man-In-The-Middle (MITM) attack.

Lastly, URL parameters are also visible in the Referer header when navigating to other websites from the vulnerable page, potentially leaking sensitive information to third party websites.

The recommended way to pass sensitive information like a JWT token is in the HTTP Authorization header, using a secure connection (HTTPS).

Steps

  • Do not send sensitive information via URL parameters.
  • Use HTTP headers or request body to send sensitive information.
  • In this case, use a POST request instead of a GET request to send the session token.
  • Encrypt the session token to protect it from being easily intercepted.
  • Implement proper session management techniques, such as using secure cookies or session storage.
  • Ensure that the session token is securely stored and transmitted over HTTPS.
  • Regularly rotate and invalidate session tokens to minimize the impact of token leakage.

Compliant code

package main

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

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

r.POST("/session", func(c *gin.Context) {
token := c.GetHeader("Authorization")
// process the token
c.String(200, "Token: %s", token)
})

r.Run() // listen and serve on 0.0.0.0:8080
}

The updated code now uses a POST request instead of a GET request to send the session token. This is a more secure method as POST requests do not expose sensitive data in the URL.

The session token is now retrieved from the HTTP headers (specifically the "Authorization" header) instead of the URL parameters. This prevents the token from being cached in the browsing history and makes it harder for attackers to obtain it.

Please note that this code assumes that the client will send the token in the "Authorization" header. You should ensure that your client-side code is updated to send the token in this way.

Additionally, you should ensure that your application is served over HTTPS. This encrypts the data between the client and the server, making it harder for attackers to intercept the token.

Finally, you should implement proper session management techniques. This includes regularly rotating and invalidating session tokens to minimize the impact of token leakage. You should also consider storing the session token in a secure cookie or session storage to further protect it.

References