Hidden fields manipulation - Go

Hidden fields manipulation - Go

Need

Prevention of unauthorized manipulation of hidden fields

Context

  • Usage of Go 1.16 for building efficient and scalable applications
  • Usage of Gin for building web applications in Go

Description

Non compliant code

        package main

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

type User struct {
	ID    int    `form:"id" json:"id"`
	Name  string `form:"name" json:"name"`
	Admin bool   `form:"admin" json:"admin"`
}

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

	r.POST("/user", func(c *gin.Context) {
		var user User
		if err := c.ShouldBind(&user); err != nil {
			c.JSON(400, gin.H{"error": err.Error()})
			return
		}

		// process the user
		// ...

		c.JSON(200, gin.H{"user": user})
	})

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

In this code snippet, we have a /user endpoint that accepts a POST request to create a new user. The request body is parsed and bound to a User struct, which includes an Admin field.

The Admin field is a hidden field that regular users should not have the ability to manipulate. However, because the application uses the ShouldBind function without any further validation, it is possible for a malicious user to include the Admin field in their request and set its value to true. This would allow them to gain admin privileges and potentially perform actions that they are not authorized to do.

This is a vulnerability because the application implicitly trusts the data it receives from the client. It does not check if the client should have the ability to set the Admin field, and blindly accepts whatever value is provided. This is an example of hidden fields manipulation, where a hidden field is included in a request and its value is changed to cause undesired behavior in the application.

Steps

  • Validate and sanitize all user input before processing it.
  • Avoid using hidden fields to store sensitive or critical information.
  • Implement proper access controls and authorization mechanisms to prevent unauthorized access or manipulation of data.
  • Use secure coding practices and follow security best practices for web application development.
  • Regularly update and patch the application and its dependencies to address any known vulnerabilities.
  • Perform security testing and code reviews to identify and fix any potential vulnerabilities.
  • Stay informed about the latest security threats and vulnerabilities in the framework and libraries used in the application.

Compliant code

        package main

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

type User struct {
	ID    int    `form:"id" json:"id"`
	Name  string `form:"name" json:"name"`
	Admin bool   `json:"admin"`
}

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

	r.POST("/user", func(c *gin.Context) {
		var user User
		if err := c.ShouldBind(&user); err != nil {
			c.JSON(400, gin.H{"error": err.Error()})
			return
		}

		// process the user
		// ...

		c.JSON(200, gin.H{"user": user})
	})

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

The original code had a vulnerability where the Admin field in the User struct was bindable from the form data. This means that a malicious user could potentially manipulate this hidden field to gain admin privileges.

The fixed code removes the form:"admin" tag from the Admin field in the User struct. This means that the Admin field can no longer be set from the form data, and can only be set internally within the application. This prevents the hidden field manipulation vulnerability.

In addition to this code fix, it's important to follow secure coding practices and regularly update and patch the application and its dependencies. Regular security testing and code reviews can help identify and fix potential vulnerabilities. It's also important to stay informed about the latest security threats and vulnerabilities in the frameworks and libraries used in the application.

References