Insecure or unset HTTP headers - Referrer-Policy - Go

Insecure or unset HTTP headers - Referrer-Policy - Go

Need

Enforcement of secure and properly configured HTTP headers - Referrer-Policy

Context

  • Usage of Go 1.16 for developing high-performance and concurrent applications
  • Usage of gin-gonic/gin 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("/", func(c *gin.Context) {
		c.String(200, "Hello, World!")
	})

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

In the above code, we are setting up a simple server using the Gin framework in Go. The server responds to GET requests at the root ("/") endpoint with "Hello, World!".

However, the code is vulnerable because it does not set the Referrer-Policy HTTP header. This header controls how much referrer information (sent via the Referer header) should be included with requests.

Not setting the Referrer-Policy or setting it to an insecure value can expose sensitive information in the URL, such as session IDs or other user-specific data, to other sites. This can lead to potential privacy leaks or other security issues.

In this case, the absence of the Referrer-Policy means that browsers will use their default behavior, which might be to send the full URL in the Referer header, potentially exposing sensitive data.

Steps

  • Add the Referrer-Policy HTTP header to the server's response.
  • Set a secure value for the Referrer-Policy header, such as 'no-referrer' or 'strict-origin-when-cross-origin'.
  • Configure the server to send the Referrer-Policy header for all responses, not just the root route ('/').
  • Test the application to ensure that the Referrer-Policy header is being set correctly.

Compliant code

        package main

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

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

	r.Use(func(c *gin.Context) {
		c.Header("Referrer-Policy", "strict-origin-when-cross-origin")
		c.Next()
	})

	r.GET("/", func(c *gin.Context) {
		c.String(200, "Hello, World!")
	})

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

The above code fixes the vulnerability by adding a middleware function that sets the Referrer-Policy HTTP header to strict-origin-when-cross-origin for all responses.

The middleware function is added using the Use function of the gin router r. This function takes a handler function as an argument, which is called for every HTTP request. The handler function sets the Referrer-Policy header using the Header method of the gin context c. The Next method is then called to pass control to the next middleware function in the chain.

The strict-origin-when-cross-origin value for the Referrer-Policy header means that the full URL will be sent as referrer to same-origin destinations, but only the origin will be sent as referrer to cross-origin destinations in a secure (HTTPS) context, and no referrer will be sent in an insecure (HTTP) context. This is a secure configuration that helps to protect sensitive information.

After adding the middleware function, the server is started with the Run method as before. The server will now send the Referrer-Policy header with all responses, not just the root route ('/').

You should test the application to ensure that the Referrer-Policy header is being set correctly. You can do this by sending a request to the server and checking the headers in the response.

References