logo

Insecure or unset HTTP headers - Content-Type - Go


Need

Enforcement of secure and appropriate Content-Type headers in server responses


Context

  1. Usage of Go 1.16 for building high-performance and concurrent applications
  2. Usage of gin-gonic/gin for building web applications and APIs in Go

Description

Insecure Code Example

package main

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

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

	r.GET("/example", func(c *gin.Context) {
		c.String(200, "OK")
	})

	r.Run()
}

In this code snippet, we are using the Gin web framework to create a simple HTTP server in Go. The server has one route, `/example`, which responds with a status code of 200 and a body of "OK". The vulnerability lies in the fact that this response does not specify a `Content-Type` header. This can lead to security issues such as MIME-type confusion, which can be exploited by attackers to execute arbitrary code in the context of the web page. The `Content-Type` header tells the client what the content type of the returned content actually is. Browsers use this information to process the content accordingly. If the `Content-Type` header is not set, browsers will try to interpret the content on their own, which can lead to unexpected results. For example, a browser might interpret the content as HTML even though it's actually plain text. This can lead to cross-site scripting (XSS) attacks if the content includes user input. In this case, since we're returning a plain text string, the `Content-Type` should be set to `text/plain`.

Steps

  1. Set the Content-Type header in the server responses.
  2. Choose an appropriate Content-Type value based on the type of data being returned (e.g., application/json for JSON data, text/html for HTML data, etc.).
  3. Use the SetHeader method in the gin.Context object to set the Content-Type header.
  4. Ensure that the Content-Type header is set before sending the response to the client.
  5. Test the application to verify that the Content-Type header is correctly set in the server responses.

Secure Code Example

package main

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

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

	r.GET("/example", func(c *gin.Context) {
		c.Header("Content-Type", "text/plain; charset=utf-8")
		c.String(200, "OK")
	})

	r.Run()
}

The updated code now includes a call to the `Header` method of the `gin.Context` object, which is used to set the `Content-Type` header in the server response. The `Content-Type` is set to `text/plain; charset=utf-8` because the server is returning a plain text response. This change ensures that the `Content-Type` header is always set in the server responses, which can help prevent certain types of security vulnerabilities related to the handling of server responses. For example, if the `Content-Type` header is not set, a client might interpret the response body incorrectly, potentially leading to issues such as cross-site scripting (XSS) attacks. By explicitly setting the `Content-Type` header, we can help ensure that the response body is interpreted correctly by the client. After making this change, you should test your application to verify that the `Content-Type` header is correctly set in the server responses. You can do this by sending a request to the server and checking the headers in the server response.


References

  • 329 - Insecure or unset HTTP headers - Content-Type

  • Last updated

    2023/09/18