Information Exposure Through Query String

ID

go.information_exposure_through_query_string

Severity

low

Remediation Complexity

medium

Remediation Risk

low

Remediation Effort

medium

Resource

Information Leak

Language

Go

Tags

ASVS50:v8.3.1, CWE:598, NIST.SP.800-53, OWASP:2025:A04, PCI-DSS:6.5.10

Description

Sensitive data — a password, token, secret or API key — is placed in a URL query string.

Rationale

Data in a URL query string is not protected the way a request body is: it is written to web-server and proxy access logs, kept in the browser history, and forwarded in the Referer header to third-party sites. Even over HTTPS the full URL, including the query string, routinely ends up in logs and history. Sending credentials or tokens this way exposes them well beyond the intended endpoint.

// VULNERABLE (outbound): the token lands in logs, history and Referer headers
url := fmt.Sprintf("https://api.example.com/data?access_token=%s", token)
login := "https://example.com/login?password=" + password

// VULNERABLE (inbound): the endpoint accepts the secret as a query/form parameter
func handler(w http.ResponseWriter, r *http.Request) {
    pwd := r.URL.Query().Get("password")
    tok := r.FormValue("access_token")
    _ = pwd
    _ = tok
}

Remediation

Send sensitive values in the request body of a POST/PUT request, or in an Authorization header — never in the URL query string.

req, _ := http.NewRequest(http.MethodPost, "https://api.example.com/data", body)
req.Header.Set("Authorization", "Bearer "+token)
// credentials go in the body, form-encoded or JSON, not the query string

References

  • CWE-598 : Use of GET Request Method With Sensitive Query Strings