Time Of Check Time Of Use in Fiber with Hmac Signatures
Time Of Check Time Of Use in Fiber with Hmac Signatures — how this specific combination creates or exposes the vulnerability
Time Of Check Time Of Use (TOCTOU) is a class of race condition where the state of a resource is checked before use, but the resource changes between the check and the actual use. In a Fiber application that uses Hmac Signatures for request authentication, a TOCTOU vulnerability can occur when signature validation and the downstream action are not performed as a single, atomic operation. For example, a handler may first verify an Hmac signature, store a derived user or role claim in memory, and then perform an authorization check or data access. If an attacker can alter the resource (such as a database row or in-memory object) between the signature validation and the use of the claim, the original trusted context can be bypassed.
Consider a scenario where a Fiber route validates an Hmac signature that includes a user ID and a role claim. The check confirms the signature is authentic, but if the handler then fetches the user from a database without re-validating that the user still holds the same role, an attacker who mutates the backend data between the signature check and the role usage can escalate privileges. This is especially relevant when the signature is used to convey authorization state rather than just integrity. The signature ensures the payload has not been tampered with in transit, but it does not protect against post-verification changes to the subject or permissions. Because the check and use are separated in time and possibly across different logical boundaries (network, process, database), the window for race conditions exists.
Another TOCTOU pattern arises when signature validation is performed on one endpoint or middleware layer, and the derived claims are passed to another handler or service call without re-verifying context. If the claims are stored in a request context that can be mutated elsewhere, or if the handler performs additional business logic that depends on stale data, the effective authorization may no longer match the original intent of the signed payload. This becomes critical in Fiber applications that chain handlers or use scoped services where state can be altered between middleware invocations. The Hmac signature remains valid, but the operational context has changed, creating a security gap.
From an API security testing perspective, middleBrick’s LLM/AI Security checks and broader authentication and BOLA/IDOR assessments can help surface these timing-related authorization risks by analyzing how claims are used after signature validation. The scanner evaluates whether authenticated endpoints properly re-validate critical attributes at the point of use, rather than relying on earlier checks. Although middleBrick does not fix the issue, its findings include prioritized guidance to help developers close timing gaps by ensuring that authorization decisions are tightly coupled with signature validation.
Hmac Signatures-Specific Remediation in Fiber — concrete code fixes
To mitigate TOCTOU when using Hmac Signatures in Fiber, ensure that validation and the subsequent use of claims happen atomically within the same handler or middleware chain, and avoid relying on mutable state between the check and the use. Below are concrete, working examples for secure Hmac verification in Fiber.
1) Atomic verification and usage in a single handler:
// main.go
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"net/http"
"github.com/gofiber/fiber/v2"
)
func main() {
app := fiber.New()
secret := []byte("super-secret-key")
app.Post("/resource", func(c *fiber.Ctx) error {
// Extract payload and signature from headers or body
payload := c.FormValue("data")
sig := c.FormValue("hmac")
// Compute Hmac and compare in constant time
mac := hmac.New(sha256.New, secret)
mac.Write([]byte(payload))
expected := hex.EncodeToString(mac.Sum(nil))
if !hmac.Equal([]byte(expected), []byte(sig)) {
return c.Status(http.StatusUnauthorized).SendString("invalid signature")
}
// Immediately use the validated payload; do not re-fetch or re-authorize from mutable state
// For example, parse embedded userID and role, then enforce authorization inline
// userID, role := extractFromPayload(payload)
// if !hasPermission(role, "write", "resource") { ... }
return c.SendString("ok")
})
app.Listen(":3000")
}
2) Re-validating critical claims at point of use within middleware, avoiding stale context:
// auth_middleware.go
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"github.com/gofiber/fiber/v2"
)
func HmacAuth(secret []byte) fiber.Handler {
return func(c *fiber.Ctx) error {
payload := c.Locals("payload").(string) // set by a prior safe step or extracted again
sig := c.Get("X-Signature", "")
mac := hmac.New(sha256.New, secret)
mac.Write([]byte(payload))
expected := hex.EncodeToString(mac.Sum(nil))
if !hmac.Equal([]byte(expected), []byte(sig)) {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "invalid hmac"})
}
// Re-derive and re-check claims right here; do not trust values set by earlier middleware
// claims := extractClaims(payload)
// c.Locals("userID", claims.userID)
// c.Locals("role", claims.role)
return c.Next()
}
}
// Usage in route definition:
// app.Post("/secure", HmacAuth([]byte("super-secret-key")), func(c *fiber.Ctx) error { ... })
3) Avoid passing validated claims to downstream handlers without re-verifying the context; prefer embedding minimal, non-mutable intent in the signed payload and re-checking permissions at the data layer. This reduces the window where TOCTOU can be exploited. middleBrick’s GitHub Action can be added to CI/CD pipelines to automatically detect insecure patterns where authorization is separated from signature validation.