HTTP Parameter Pollution

ID

go.http_parameter_pollution

Severity

high

Resource

Injection

Language

Go

Tags

CWE:235, NIST.SP.800-53, OWASP:2021:A3, PCI-DSS:6.5.1

Description

Improper neutralization of special elements into path, query string, or parameters of HTTP requests

Rationale

HTTP Parameter Pollution occurs when a web application inadequately handles parameters that are included in an HTTP request. By injecting additional parameters into a query string or request body, an attacker can manipulate the request path and parameters to override intended behavior or bypass certain validations, potentially accessing unauthorized data or altering application logic.

In contrast to Server-Side Request Forgery (SSRF), where an attacker controls the full request URL including the host and port, HPP focuses on manipulating parts like the path, query, or fragment of the URL. Common attack vectors exploit characters such as "&" to inject additional parameters, "../" to alter the path, ";" to add matrix parameters, and "#" to truncate URL components.

package main

import (
    "fmt"
    "io"
    "net/http"
    "time"
)

func handler(w http.ResponseWriter, r *http.Request) {
    // Read only the first occurrence of 'target'
    target := r.URL.Query().Get("target")
    if target == "" {
        http.Error(w, "missing 'target' parameter", http.StatusBadRequest)
        return
    }

    client := &http.Client{Timeout: 5 * time.Second}
    req, err := http.NewRequest("GET", target, nil) // FLAW
    if err != nil {
        http.Error(w, fmt.Sprintf("failed to create request: %v", err), http.StatusInternalServerError)
        return
    }

    resp, err := client.Do(req)
    if err != nil {
        http.Error(w, fmt.Sprintf("request failed: %v", err), http.StatusInternalServerError)
        return
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        http.Error(w, fmt.Sprintf("failed to read response: %v", err), http.StatusInternalServerError)
        return
    }

    w.Write(body)
}

If an attacker sends a request like: GET /?target=http://internal.service&target=http://malicious.com

The Go server will call http.NewRequest("GET", target, nil) with only the first value (http://internal.service), but logging or other downstream components might behave differently if they process all values (e.g. [internal.service, malicious.com]). This can lead to inconsistent behavior, security misrouting, or even SSRF if not properly controlled.

Remediation

To remediate HTTP Parameter Pollution vulnerabilities, implement the following practices:

  1. Input Validation and Encoding: Validate user input rigorously. Use encoding to ensure any special characters in input are safely included in URLs, preventing them from manipulating the request structure.

  2. Parameter Handling: Instead of constructing URLs via string concatenation, utilize URI building classes (e.g., Spring’s UriComponentsBuilder) to safely handle and encode all parts of the URL, ensuring parameter integrity.

  3. Secure Framework Configuration: Consider using framework settings that limit or restrict parameter resolution from multiple sources, and ensure only expected parameters are processed.

Configuration

The detector has the following configurable parameters:

  • sources, that indicates the source kinds to check.

  • neutralizations, that indicates the neutralization kinds to check.

Unless you need to change the default behavior, you typically do not need to configure this detector.

References