HIGH time of check time of usefiberbasic auth

Time Of Check Time Of Use in Fiber with Basic Auth

Time Of Check Time Of Use in Fiber with Basic Auth — how this specific combination creates or exposes the vulnerability

Time Of Check Time Of Use (TOCTOU) is a class of race condition where a system checks a property (such as authentication or authorization) and later uses the result of that check to make a security decision. In the Fiber web framework for Go, combining Basic Auth with this pattern can expose endpoints to authorization bypass if the check and the state used for enforcement are not atomic with respect to changes in user identity or permissions.

Consider an endpoint that first validates a Basic Auth username and password, stores the resulting identity in a request context, and later performs a permission check against a resource (e.g., a record ID). If an attacker can cause the identity or permissions to change between the check and the use—such as by revoking or altering credentials mid-request on the server side, or by manipulating concurrent requests—the earlier check may no longer be valid when the actual resource access occurs. Because Fiber allows handlers to mutate context and because Basic Auth credentials are typically decoded per request, a non-atomic sequence like validateBasicAuth followed by fetchAndServeResource can lead to accessing a resource the caller should not see.

With Basic Auth, each request typically carries an Authorization header that is base64-encoded username:password. If your application decodes this once, places the user into context, and later relies on that context without re-verifying the credential or binding the authorization decision to the original credential, you risk TOCTOU. For example, if server-side logic can change a user’s role or token validity between the check and the data fetch, concurrent requests or slow handlers may observe inconsistent authorization states. This is especially relevant when handlers perform multiple operations per request (e.g., checking access to one resource before retrieving another) and do not re-authenticate or re-authorize at the point of use.

In distributed or high-concurrency settings, TOCTOU with Basic Auth in Fiber can manifest when handlers share mutable state or rely on cached user data without considering staleness. An attacker does not need to break cryptography; they exploit timing and state changes to slip through a check that appeared valid moments earlier. Because Basic Auth is stateless per request, the onus is on the application to ensure that authorization decisions are tied tightly to the credentials presented and verified within the same, well-scoped operation.

Basic Auth-Specific Remediation in Fiber — concrete code fixes

To mitigate TOCTOU with Basic Auth in Fiber, design handlers so that authentication and authorization happen atomically within the same, non-interruptible scope and avoid relying on mutable context that can change mid-request. Prefer middleware that validates credentials and immediately enforces access control for the specific target resource, rather than decoupling check and use.

Below are concrete, working Fiber examples that demonstrate a vulnerable pattern and a remediated pattern.

Vulnerable pattern: check then use

// DO NOT DO THIS: TOCTOU risk with Basic Auth in Fiber
func vulnerableHandler(c *fiber.Ctx) error {
    user, pass, err := c.Request().AuthUser(), c.Request().AuthPassword(), nil
    if err != nil {
        return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "missing auth"})
    }
    // Check: validate credentials
    u, err := userService.Validate(user, pass)
    if err != nil || !u.Active {
        return c.Status(fiber.StatusForbidden).JSON(fiber.Map{"error": "invalid credentials"})
    }
    // Use: fetch resource with authorization decision based on stale context
    resourceID := c.Params("id")
    // Risk: user or permissions may have changed between Validate and AuthorizeResource
    if !authService.AuthorizeResource(u.ID, resourceID) {
        return c.Status(fiber.StatusForbidden).JSON(fiber.Map{"error": "not allowed"})
    }
    data, err := dataService.Fetch(resourceID)
    if err != nil {
        return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "server error"})
    }
    return c.JSON(data)
}

The sequence Validate → AuthorizeResource → Fetch creates a window where user state can change on the server, exposing TOCTOU.

Remediated pattern: combine check and use atomically

// DO THIS: bind authentication to the authorization decision for the specific resource
func secureHandler(c *fiber.Ctx) error {
    user, pass, err := c.Request().AuthUser(), c.Request().AuthPassword(), nil
    if err != nil {
        return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "missing auth"})
    }
    resourceID := c.Params("id")
    // Atomic check-and-use: validate and authorize in one flow scoped to this resource
    decision, err := authService.DecisionForResource(user, pass, resourceID)
    if err != nil {
        return c.Status(fiber.StatusForbidden).JSON(fiber.Map{"error": "not authorized"})
    }
    if !decision.Allowed {
        return c.Status(fiber.StatusForbidden).JSON(fiber.Map{"error": "not allowed"})
    }
    data, err := dataService.Fetch(resourceID)
    if err != nil {
        return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "server error"})
    }
    return c.JSON(data)
}

In the remediated pattern, DecisionForResource encapsulates credential validation and per-resource authorization in a single operation, eliminating the window for state change between check and use. This aligns with secure coding practices that bind authorization tightly to the original credentials and minimize shared mutable context.

Additional recommendations: avoid storing user claims in mutable global or package-level state between requests; re-validate credentials at the point of sensitive operations when feasible; and design handlers to be idempotent with respect to authorization inputs. These practices reduce the attack surface for race conditions in Fiber applications using Basic Auth.

Frequently Asked Questions

How can I test if my Fiber Basic Auth endpoint is vulnerable to TOCTOU?
Send concurrent requests where credentials are changed server-side between validation and resource access, and check whether a resource is returned after the credential change. Instrument logging to verify that authorization decisions are tied to the credentials presented in the same handler flow.
Does using middleware eliminate TOCTOU with Basic Auth in Fiber?
Middleware reduces risk only if it performs authentication and authorization atomically for each request and does not rely on mutable context that can change between check and use. Ensure middleware binds authorization decisions to the specific resource and revalidates when necessary rather than storing user state for later use.