Crlf Injection in Fiber with Basic Auth
Crlf Injection in Fiber with Basic Auth — how this specific combination creates or exposes the vulnerability
Crlf Injection occurs when an attacker can inject carriage return (CR, \r) and line feed (\n) characters into HTTP headers, causing header injection or response splitting. In the Fiber web framework for Go, this risk is particularly relevant when Basic Authentication is handled in a way that incorporates untrusted input directly into header values or logs without sanitization.
Basic Auth in Fiber typically involves extracting the Authorization header, decoding the base64-encoded credentials, and using the username or password in business logic or logging. If an attacker supplies a username like admin\r\nX-Injected: true, and the application concatenates or logs this value into a new header or response without validation, the injected CRLF sequence can split the response. This can lead to HTTP response splitting, header injection, or cache poisoning. Even in unauthenticated scans, middleBrick tests for CRLF injection as one of its 12 parallel security checks, flagging endpoints where user-controlled data reaches headers or logs.
When Basic Auth credentials are processed in Fiber, the risk is not just about parsing the Authorization header itself, but about downstream handling. For example, if the decoded username is later used in a custom header, a log entry, or an error message without proper sanitization, the injected CRLF can alter the structure of the HTTP message. This can expose sensitive information in headers or enable HTTP response splitting attacks, which may facilitate cross-user or cross-origin attacks in certain server configurations. middleBrick’s authentication and BOLA/IDOR checks often surface these weaknesses by observing whether injected CRLF characters are reflected in headers or logs during unauthenticated testing.
Moreover, since Basic Auth credentials are base64-encoded rather than encrypted, any leakage or manipulation in logs or error responses can expose usernames and server-side behavior. The combination of Fiber’s flexible middleware chaining and improper input validation around the Authorization header amplifies the potential impact. middleBrick’s data exposure and encryption checks help detect whether CRLF-related weaknesses lead to unintended information disclosure in headers or logs.
Basic Auth-Specific Remediation in Fiber — concrete code fixes
To mitigate CRLF injection in Fiber when using Basic Authentication, ensure that any user-controlled data derived from credentials is strictly validated and never directly concatenated into headers or logs. The following examples show secure handling patterns.
1. Validate and sanitize the Authorization header
Always parse the Authorization header carefully and avoid reflecting raw credential values into other headers or responses.
package main
import (
"encoding/base64"
"fmt"
"net/http"
"strings"
"github.com/gofiber/fiber/v2"
)
func basicAuthMiddleware(c *fiber.Ctx) error {
auth := c.Get(fiber.HeaderAuthorization)
if auth == "" {
return c.SendStatus(fiber.StatusUnauthorized)
}
const prefix = "Basic "
if !strings.HasPrefix(auth, prefix) {
return c.SendStatus(fiber.StatusUnauthorized)
}
payload, err := base64.StdEncoding.DecodeString(auth[len(prefix):])
if err != nil {
return c.SendStatus(fiber.StatusUnauthorized)
}
pair := strings.SplitN(string(payload), ":", 2)
if len(pair) != 2 {
return c.SendStatus(fiber.StatusUnauthorized)
}
username, password := pair[0], pair[1]
// Sanitize: reject CRLF characters in credentials
if strings.ContainsAny(username, "\r\n") || strings.ContainsAny(password, "\r\n") {
return c.SendStatus(fiber.StatusBadRequest)
}
// Secure usage: do not embed username/password in headers
c.Locals("user", username)
return c.Next()
}
func main() {
app := fiber.New()
app.Use(basicAuthMiddleware)
app.Get("/profile", func(c *fiber.Ctx) error {
user := c.Locals("user").(string)
// Use user in a safe way, e.g., lookup in a database
return c.JSON(fiber.Map{"profile": fmt.Sprintf("Hello, %s", user)})
})
app.Listen(":3000")
}
2. Avoid logging or echoing raw credentials
Ensure logs and error messages do not include raw usernames or passwords. If logging is necessary, sanitize values to remove or replace CRLF characters.
import (
"log"
"strings"
)
func safeLogUser(username string) {
// Remove any CRLF to prevent log injection
sanitized := strings.ReplaceAll(strings.ReplaceAll(username, "\r", "_"), "\n", "_")
log.Printf("auth_attempt user=%s", sanitized)
}
3. Use structured data instead of header concatenation
If you need to pass user context to downstream handlers, use Fiber’s context locals or structured metadata rather than building new headers with user input.
app.Use(func(c *fiber.Ctx) error {
auth := c.Get(fiber.HeaderAuthorization)
// ... decode and validate as above
c.Locals("auth_user", username)
c.Locals("auth_role", determineRole(username))
return c.Next()
})
app.Get("/admin", func(c *fiber.Ctx) error {
role := c.Locals("auth_role")
if role != "admin" {
return c.SendStatus(fiber.StatusForbidden)
}
return c.SendString("admin only")
})
By strictly validating credentials and avoiding the use of raw user input in headers or logs, you can prevent CRLF injection while still using Basic Authentication securely in Fiber. middleBrick’s authentication and data exposure checks can help verify that these mitigations are effective during scans.