Timing Attack in Fiber with Basic Auth
Timing Attack in Fiber with Basic Auth — how this specific combination creates or exposes the vulnerability
A timing attack in the Fiber framework becomes relevant when HTTP Basic Authentication is used without constant-time comparison for credentials. Basic Auth transmits a username and password encoded in Base64 inside the Authorization header. On the server, decoding the header and validating credentials typically involves string comparison. If the comparison short-circuits on the first mismatched byte, an attacker can learn partial information about the expected value based on differences in response time.
In Fiber, this risk exists when authentication logic compares a user-supplied password or token against a stored value using standard equality checks. An attacker can send many requests with slightly altered credentials and measure round-trip times. Longer response times may indicate a correct prefix, allowing an attacker to iteratively guess a valid password or token byte by byte. This is a classic oracle-based timing attack, where the server unintentionally leaks information through timing variance rather than explicit error messages.
The attack surface is unauthenticated because middleBrick scans the endpoint without credentials and can detect timing differences in challenge and response behavior. A scan can observe whether certain malformed or partial credentials lead to disproportionately slower responses, suggesting that validation logic is not constant-time. This is especially important when Basic Auth is used over TLS, as the transport encryption does not prevent application-layer timing leaks.
For example, if a developer compares the decoded password like this in Go:
if string(decodedPassword) == storedPassword { /* grant access */ }
The equality check may exit early on mismatch. An attacker controlling the decodedPassword can infer byte-by-byte matches by observing response durations across many requests.
middleBrick includes a Rate Limiting check among its 12 parallel security checks, which can indirectly highlight inconsistent timing behavior when requests are throttled differently. In combination with the Authentication check, this helps identify endpoints where timing-based leakage may occur. Note that middleBrick detects and reports these patterns without attempting to exploit them, providing remediation guidance to help developers write constant-time comparison logic.
Basic Auth-Specific Remediation in Fiber — concrete code fixes
To mitigate timing attacks when using HTTP Basic Authentication in Fiber, ensure credential comparisons are performed in constant time. In Go, avoid early-exit string comparisons and instead use a fixed-time comparison that always processes all bytes regardless of early mismatches.
A secure approach uses the subtle.ConstantTimeCompare function from crypto/subtle. Since Basic Auth credentials are often compared as strings or byte slices, convert both sides to fixed-length byte representations before comparison. Below is a safe implementation example:
package main
import (
"crypto/subtle"
"encoding/base64"
"strings"
"github.com/gofiber/fiber/v2"
)
func isValidBasicAuth(c *fiber.Ctx, expectedUser, expectedPass string) bool {
auth := c.Get("Authorization")
if len(auth) < 6 || strings.SplitN(auth, " ", 2)[0] != "Basic" {
return false
}
decoded, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(auth, "Basic "))
if err != nil {
return false
}
parts := strings.SplitN(string(decoded), ":", 2)
if len(parts) != 2 {
return false
}
user, pass := parts[0], parts[1]
if subtle.ConstantTimeCompare([]byte(user), []byte(expectedUser)) != 1 {
return false
}
return subtle.ConstantTimeCompare([]byte(pass), []byte(expectedPass)) == 1
}
func main() {
app := fiber.New()
app.Get("/protected", func(c *fiber.Ctx) error {
if !isValidBasicAuth(c, "admin", "s3cur3P@ss") {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "invalid credentials"})
}
return c.JSON(fiber.Map{"message": "authenticated"})
})
app.Listen(":3000")
}
This approach ensures that both username and password comparisons take the same amount of time regardless of how many bytes match, reducing the risk of a timing attack. It also avoids leaking information through error paths by returning a generic failure response.
Beyond code, consider rotating credentials regularly and enforcing transport-layer security. While these steps do not directly prevent timing attacks, they reduce the overall risk profile. middleBrick can validate that your authentication endpoints resist timing-based inference by checking for consistent response characteristics across multiple requests, providing findings and remediation guidance within its standard security checks.