Dictionary Attack in Fiber
How Dictionary Attack Manifests in Fiber
In Go's Fiber framework, dictionary attacks against authentication endpoints (e.g., /login) exploit the absence of rate limiting and weak credential validation. A typical vulnerable pattern is a plain authentication handler that checks credentials without throttling repeated attempts.
Consider this common Fiber handler:
// VULNERABLE: No rate limiting, weak comparison
app.Post("/login", func(c *fiber.Ctx) error {
var credentials struct {
Username string `json:"username"`
Password string `json:"password"`
}
if err := c.BodyParser(&credentials); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid request body",
})
}
// Direct database lookup and plaintext comparison (anti-pattern)
user, err := db.GetUserByUsername(credentials.Username)
if err != nil || user.Password != credentials.Password {
// Informative error reveals valid usernames
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"error": "Invalid credentials",
})
}
// Issue session/JWT token...
return c.JSON(fiber.Map{"status": "success"})
})This code has two critical flaws for dictionary attacks:
- No request throttling: An attacker can submit thousands of password guesses per minute from a single IP.
- Timing side-channel: Even with constant-time comparison, the early database lookup (
db.GetUserByUsername) fails faster for non-existent usernames, allowing user enumeration.
Fiber's middleware chain is where defenses should be inserted. A missing RateLimiter middleware on the login route is a direct invitation for automated credential stuffing.
Fiber-Specific Detection
Detecting dictionary attack vulnerabilities in Fiber APIs involves both code review and dynamic testing. Look for:
- Authentication endpoints (
POST /login,POST /auth/token) without rate limiting middleware. - Informative error messages that differentiate between "invalid username" and "invalid password".
- Absence of account lockout or progressive delay mechanisms after failed attempts.
Dynamic scanning with middleBrick's CLI or GitHub Action can automate this detection. The tool's Rate Limiting and Authentication checks will probe your Fiber endpoint:
$ middlebrick scan https://api.example.com/login
--- middleBrick Security Report ---
Endpoint: POST https://api.example.com/login
Risk Score: 42/100 (F - Critical)
Critical Findings:
1. Rate Limiting Missing (Severity: Critical)
- No X-RateLimit-* headers detected after 20 rapid requests
- Remains accessible after 100+ sequential attempts from same IP
2. User Enumeration (Severity: High)
- Response time differs by ~150ms for existing vs non-existing usernames
- Error message: "Invalid credentials" (does not obscure user existence)middleBrick's LLM/AI Security checks also scan for these patterns if the login endpoint processes AI-generated inputs, though that's less common in Fiber auth handlers. The Pro tier's continuous monitoring will alert you if a new Fiber deployment accidentally removes rate limiting.
Fiber-Specific Remediation
Remediation in Fiber leverages its middleware ecosystem. Implement these patterns:
1. Apply Rate Limiting Middleware
Use Fiber's built-in limiter.New or a robust alternative like golang.org/x/time/rate. Configure per-route limits for auth endpoints:
import "github.com/gofiber/fiber/v2/middleware/limiter"
// Configure strict limits for login route
app.Post("/login", limiter.New(limiter.Config{
Max: 5, // Max 5 requests
Expiration: 5 * time.Minute,
KeyGenerator: func(c *fiber.Ctx) string {
// Rate limit by IP + username to prevent IP rotation bypass
return c.IP() + ":" + c.FormValue("username")
},
OnSuccess: func(c *fiber.Ctx) error {
return c.Next()
},
OnLimitReached: func(c *fiber.Ctx) error {
return c.Status(fiber.StatusTooManyRequests).JSON(fiber.Map{
"error": "Too many attempts. Please try later.",
})
},
}))
// Your actual login handler
app.Post("/login", loginHandler)2. Constant-Time Comparison & Generic Errors
Always use crypto/constanttime for password checks and return identical errors regardless of user existence:
import "crypto/subtle"
func loginHandler(c *fiber.Ctx) error {
var credentials struct {
Username string `json:"username"`
Password string `json:"password"`
}
if err := c.BodyParser(&credentials); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request"})
}
user, err := db.GetUserByUsername(credentials.Username)
if err != nil || user == nil {
// Simulate delay even for non-existent users
time.Sleep(100 * time.Millisecond)
return genericAuthError()
}
// Constant-time password comparison
if subtle.ConstantTimeCompare([]byte(user.PasswordHash), []byte(credentials.Password)) != 1 {
time.Sleep(100 * time.Millisecond)
return genericAuthError()
}
// Success path...
return c.JSON(fiber.Map{"status": "authenticated"})
}
func genericAuthError() error {
return fiber.NewError(fiber.StatusUnauthorized, "Invalid username or password")
}3. Account Lockout (Optional)
For high-security apps, implement progressive delays or temporary lockouts using Redis (via github.com/go-redis/redis/v8) to track failed attempts per account/IP. Fiber's ctx.Locals can store per-request state, but persistent tracking requires external storage.
After applying these fixes, rescan with middlebrick scan or the GitHub Action to verify the Rate Limiting finding is resolved and the score improves.
Integration with CI/CD and Development Workflow
Embedding dictionary attack prevention into your Fiber development lifecycle ensures regressions are caught early. Use middleBrick's GitHub Action in your workflow to scan staging APIs before deployment:
# .github/workflows/api-security.yml
name: API Security Scan
on:
pull_request:
paths:
- 'api/**' # Your Fiber service code
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to staging
run: ./deploy-staging.sh # Your Fiber app to staging URL
- name: Run middleBrick scan
uses: middlebrick/github-action@v1
with:
url: ${{ secrets.STAGING_URL }}/login
fail_below: 80 # Fail PR if score drops below B
env:
MIDDLEBRICK_API_KEY: ${{ secrets.MIDDLEBRICK_KEY }}For local development, the CLI tool (npm install -g middlebrick) lets you scan your local Fiber server (middlebrick scan http://localhost:3000/login) before committing. The MCP Server integration allows scanning directly from AI assistants like Cursor when reviewing Fiber code, providing immediate feedback on missing rate limiting.
These integrations shift security left, preventing dictionary attack vulnerabilities from reaching production where credential stuffing could lead to data breaches.
Frequently Asked Questions
How does middleBrick detect dictionary attack vulnerabilities in a Fiber API?
X-RateLimit-* headers, lack of 429 Too Many Requests responses, and timing side-channels in login endpoints. The scan also correlates findings with your OpenAPI spec to ensure all auth routes are covered.What's the difference between middleBrick's Rate Limiting check and a generic scanner?
POST /login specifically, and measures actual request throughput. It also correlates with the Authentication check to see if rate limiting is disabled after a certain number of failures—a misconfiguration unique to frameworks like Fiber where middleware order matters.