Skip to main content

HTTP parameter pollution

Need

Prevention of HTTP parameter pollution

Context

  • Usage of Go 1.16 for building high-performance 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("/user", func(c *gin.Context) {
username := c.Query("username")
password := c.Query("password")
c.JSON(200, gin.H{
"username": username,
"password": password,
})
})

r.Run()
}

In the above code, we have a basic Go server application using the Gin framework. This application has a single endpoint /user that accepts GET requests.

The vulnerability lies in the fact that the application does not validate or sanitize the incoming HTTP parameters. The application simply takes the username and password parameters from the HTTP request and returns them in the response.

This is a classic example of HTTP Parameter Pollution (HPP). An attacker can inject extra parameters into the HTTP request, causing unexpected behavior on the server. For example, an attacker could inject a username parameter with a value that includes a SQL injection attack, potentially compromising the server's database.

Furthermore, the application does not check if the username and password parameters are provided more than once in the request. If these parameters are repeated with different values, the Gin framework will only consider the first occurrence, potentially leading to further unexpected behavior.

This vulnerability can be exploited by an attacker to manipulate the application's behavior and potentially gain unauthorized access or extract sensitive information.

Steps

  • Validate and sanitize input parameters
  • Use a whitelist approach to only allow expected parameters
  • Implement proper input validation and parameter handling
  • Avoid using user-supplied input directly in the response
  • Consider using a framework or library that handles input validation and parameter handling automatically

Compliant code

package main

import (
"github.com/gin-gonic/gin"
"net/http"
"strings"
)

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

r.GET("/user", func(c *gin.Context) {
username := c.Query("username")
password := c.Query("password")

// Validate and sanitize input parameters
if strings.TrimSpace(username) == "" || strings.TrimSpace(password) == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid parameters"})
return
}

// Avoid using user-supplied input directly in the response
c.JSON(200, gin.H{
"message": "User details received",
})
})

r.Run()
}

The updated code includes validation and sanitization of the input parameters. It checks if the username and password parameters are not empty. If either of them is empty, it returns a 400 Bad Request status with an error message.

The code also avoids using user-supplied input directly in the response. Instead of returning the username and password in the response, it returns a generic message indicating that the user details have been received.

This approach helps to prevent HTTP Parameter Pollution (HPP) attacks by ensuring that only valid and expected parameters are processed by the server. It also helps to protect sensitive user information by not including it directly in the response.

Remember, it's always a good practice to validate and sanitize all user-supplied input to protect your application from various types of security vulnerabilities, including HPP.

References