Skip to main content

Insecurely generated cookies

Need

Secure generation and handling of cookies

Context

  • Usage of Go 1.16 for building efficient and scalable 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("/cookie", func(c *gin.Context) {
c.SetCookie("sensitiveCookie", "sensitiveValue", 60, "/", "localhost", false, false)
c.JSON(200, gin.H{
"message": "cookie set",
})
})

r.Run()
}

The above Go code uses the Gin web framework to create a cookie named sensitiveCookie with a value of sensitiveValue. The cookie is set to expire after 60 seconds.

The function SetCookie has the following parameters:

func (c *Context) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool)

Here is a brief overview of what each parameter represents:

  • name: the name of the cookie
  • value: the value of the cookie
  • maxAge: the maximum age of the cookie
  • path: the path of the cookie
  • domain: the domain of the cookie
  • secure: a boolean value indicating whether the cookie is secure or not
  • httpOnly: a boolean value indicating whether the cookie is accessible only over HTTP or not

The vulnerability lies in the last two parameters of the SetCookie function. The secure parameter is set to false, which means the cookie can be transmitted over an unencrypted HTTP connection. If an attacker is able to intercept the HTTP traffic (for example, via a man-in-the-middle attack), they could potentially steal the cookie and use it to impersonate the user.

The httpOnly parameter is also set to false, which means the cookie can be accessed by client-side scripts. This makes the cookie vulnerable to cross-site scripting (XSS) attacks. If an attacker can execute a script on the client's browser, they can steal the cookie and use it to impersonate the user.

To fix this vulnerability, both the secure and httpOnly parameters should be set to true. This ensures that the cookie is only transmitted over an encrypted HTTPS connection and cannot be accessed by client-side scripts.

Steps

  • Use the Secure flag when setting the cookie to ensure it is only sent over HTTPS.
  • Set the HttpOnly flag to prevent client-side scripts from accessing the cookie.
  • Use the SameSite attribute to restrict the cookie to be sent only in same-site requests.
  • Generate a strong and unique value for the cookie's secret key.
  • Set the MaxAge attribute to an appropriate value to control the cookie's expiration time.
  • Set the Path attribute to restrict the cookie to a specific path on the server.
  • Consider using a library or framework that provides built-in secure cookie handling.

Compliant code

package main

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

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

r.GET("/cookie", func(c *gin.Context) {
c.SetCookie("sensitiveCookie", "sensitiveValue", 60, "/", "localhost", true, true)
c.JSON(200, gin.H{
"message": "cookie set",
})
})

r.Run()
}

The original code was setting a cookie without the Secure and HttpOnly flags. The Secure flag ensures that the cookie is only sent over HTTPS, preventing it from being sent in plain text. The HttpOnly flag prevents client-side scripts from accessing the cookie, protecting it from cross-site scripting (XSS) attacks.

In the fixed code, we set the Secure and HttpOnly flags to true when setting the cookie:

c.SetCookie("sensitiveCookie", "sensitiveValue", 60, "/", "localhost", true, true)

This ensures that the cookie is only sent over HTTPS and cannot be accessed by client-side scripts.

Please note that this is a basic fix. For a more secure solution, consider the following:

  • Use the SameSite attribute to restrict the cookie to be sent only in same-site requests.
  • Generate a strong and unique value for the cookie's secret key.
  • Set the MaxAge attribute to an appropriate value to control the cookie's expiration time.
  • Set the Path attribute to restrict the cookie to a specific path on the server.
  • Consider using a library or framework that provides built-in secure cookie handling.

References