Password In Redirect
ID |
go.password_in_redirect |
Severity |
critical |
Resource |
Information Leak |
Language |
Go |
Tags |
CWE:359, NIST.SP.800-53, OWASP:2021:A7, PCI-DSS:6.5.3 |
Description
Sensitive information such as passwords must not be included in URL redirects, as URLs may be logged or cached, exposing confidential data.
Rationale
Including passwords or other sensitive data in URLs during a redirect can lead to information leakage. URLs may be stored in browser history, server logs, reverse proxies, analytics tools, or leaked through the Referer header if the user clicks on another link. CWE-359 ("Exposure of Private Personal Information to an Unauthorized Actor") applies when sensitive information is inadvertently exposed.
In Go web applications using the net/http
package, it’s common to perform redirects using http.Redirect()
. However, appending query parameters such as ?password=secret
to the redirection target introduces risk:
http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
username := r.FormValue("username")
password := r.FormValue("password")
// BAD: password is exposed in the URL
target := fmt.Sprintf("/welcome?user=%s&password=%s", username, password)
http.Redirect(w, r, target, http.StatusFound)
})
This practice exposes the password in logs and browser history. Instead, sensitive information should be handled via secure session management mechanisms or request bodies.
Remediation
Do not place sensitive data in redirect URLs. Use secure mechanisms such as:
-
HTTP cookies (preferably with
Secure
andHttpOnly
flags) -
Session storage (e.g., server-side session state with UUID)
-
Avoid passing passwords around post-authentication; authenticate once and establish a session
Refactored example using secure sessions:
http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
username := r.FormValue("username")
password := r.FormValue("password")
if authenticate(username, password) {
sessionID := createSession(username) // Store session in memory/db
cookie := http.Cookie{
Name: "session_id",
Value: sessionID,
Path: "/",
HttpOnly: true,
Secure: true,
}
http.SetCookie(w, &cookie)
http.Redirect(w, r, "/welcome", http.StatusFound)
} else {
http.Redirect(w, r, "/login?error=invalid", http.StatusFound)
}
})
This avoids placing the password in a redirect URL and ensures proper confidentiality of user credentials.