Crlf Injection in Gin with Basic Auth
Crlf Injection in Gin with Basic Auth — how this specific combination creates or exposes the vulnerability
Crlf Injection occurs when user-controlled data is reflected in HTTP headers without sanitization, allowing an attacker to inject newline characters (\r\n) to split the header stream. In Gin, this commonly arises when dynamic values such as usernames or tokens from Basic Auth are placed into response headers like X-User-Name or X-Trace-ID. Basic Auth credentials are decoded from the Authorization header on each request; if the application uses parts of the decoded username in headers without validation, an attacker can embed carriage return and line feed sequences to inject additional headers or perform HTTP response splitting.
When Basic Auth is used, Gin typically parses credentials via middleware that decodes the base64-encoded Authorization: Basic header into username and password. If the username (or password) is later written into a header, cookie, or response body without proper escaping, Crlf Injection becomes possible. For example, a username like alice\r\nX-Injected: true (when base64-encoded and sent in the Authorization header) can cause Gin to append an extra X-Injected: true header if the application logic does not sanitize the value. This can enable HTTP response splitting, cache poisoning, or the injection of malicious redirects, depending on how downstream proxies or browsers handle the malformed response.
The interaction with Basic Auth also affects logging and monitoring. Gin’s default access logs may include the username, and if log entries are constructed by concatenating header-like fields without escaping, injected newlines can forge log entries or bypass log parsing rules. Because the attack surface involves both authentication parsing and header manipulation, Crlf Injection in this context can be subtle: the malicious input originates from a trusted channel (the Authorization header) and is later reflected in another header or line-based construct. Detecting such issues requires correlating authentication events with header-level output checks, which is why scanning tools that test unauthenticated attack surfaces and inspect header handling are valuable for identifying these patterns before exploitation.
Basic Auth-Specific Remediation in Gin — concrete code fixes
To prevent Crlf Injection when using Basic Auth in Gin, ensure that any user-derived data—especially the decoded username or password—is sanitized before being used in headers, cookies, or response lines. The safest approach is to treat the Authorization header as opaque and avoid reusing its components in mutable headers. If you must include user information in headers, strip or encode newline characters explicitly.
Below are two concrete examples. The first demonstrates a vulnerable pattern where the username is used directly in a custom header. The second shows a remediated version that removes carriage return and line feed characters, mitigating injection risk.
// Vulnerable example: username reflected in a header without sanitization
func handler(c *gin.Context) {
user, pass, ok := c.Request.BasicAuth()
if !ok {
c.AbortWithStatusJSON(401, gin.H{"error": "authorization required"})
return
}
// WARNING: user may contain \r\n
c.Header("X-User-Name", user)
c.JSON(200, gin.H{"ok": true})
}
// Remediated example: sanitize user input before using in headers
func handler(c *gin.Context) {
user, pass, ok := c.Request.BasicAuth()
if !ok {
c.AbortWithStatusJSON(401, gin.H{"error": "authorization required"})
return
}
// Remove CR and LF characters to prevent header injection
sanitizedUser := strings.ReplaceAll(strings.ReplaceAll(user, "\r", ""), "\n", "")
c.Header("X-User-Name", sanitizedUser)
c.JSON(200, gin.H{"ok": true})
}
In addition to sanitization, prefer not to echo Basic Auth-derived values into headers at all. Use standard mechanisms for user context, such as request-scoped values via c.Set and c.Get, which keep data internal to the application and avoid header reflection entirely. If you need to track authentication for logging or tracing, encode or hash the username rather than passing it literally. These practices reduce the likelihood of Crlf Injection and align with secure handling of credentials in HTTP middleware.