Lack of data validation - Type confusion - Go

Lack of data validation - Type confusion - Go

Need

Implementation of robust data validation and type checking

Context

  • Usage of Go 1.16 for building high-performance and scalable applications
  • Usage of gin-gonic/gin for building web applications and APIs in Go

Description

Non compliant code

        package main

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

func main() {
	r := gin.Default()
	r.POST("/endpoint", func(c *gin.Context) {
		var input map[string]interface{}
		c.BindJSON(&input)
		val := input["value"]
		// Processing the value
		// ...
	})
	r.Run()
}
        
        

The code above is a simple server application written in Go using the Gin framework. It exposes a POST endpoint at "/endpoint".

When a POST request is sent to "/endpoint", it binds the JSON body of the request to a map, input. It then retrieves the value associated with the key "value" from the map.

The vulnerability lies in the fact that the server does not validate the type of the value associated with the key "value". The server is supposed to accept only numbers but due to lack of data validation, it also accepts values in the form 0xff which represents hexadecimal numbers.

This is a type confusion vulnerability as the server is interpreting the input as a different type than what is expected. This could lead to unexpected behavior and potential security risks such as denial of service, incorrect behavior, or even remote code execution depending on what the server does with the input.

Steps

  • Implement data validation on the server-side to ensure that the 'value' field only accepts valid numeric values.
  • Use appropriate data types to store and process the 'value' field, such as integers or floats, depending on the expected input.
  • Consider using a validation library or framework to simplify the data validation process.
  • Handle any potential type confusion issues by explicitly converting the input to the expected data type before processing it.
  • Avoid relying solely on client-side validation as it can be bypassed easily. Always perform server-side validation to ensure data integrity and security.

Compliant code

        package main

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

func main() {
	r := gin.Default()
	r.POST("/endpoint", func(c *gin.Context) {
		var input map[string]interface{}
		c.BindJSON(&input)
		val, ok := input["value"].(string)
		if !ok {
			c.JSON(400, gin.H{
				"error": "Invalid value type",
			})
			return
		}
		_, err := strconv.Atoi(val)
		if err != nil {
			c.JSON(400, gin.H{
				"error": "Invalid value format",
			})
			return
		}
		// Processing the value
		// ...
	})
	r.Run()
}
        
        

The updated code includes server-side validation to ensure that the 'value' field only accepts valid numeric values.

Firstly, we check if the 'value' field is a string using a type assertion. If the type assertion fails, we return a 400 status code with an error message indicating that the value type is invalid.

Next, we use the strconv.Atoi function to try to convert the string to an integer. If the conversion fails (i.e., the string is not a valid integer), we return a 400 status code with an error message indicating that the value format is invalid.

This way, we ensure that the 'value' field is a valid integer before we proceed with processing it. This prevents type confusion issues and ensures data integrity and security.

References