CRITICAL dictionary attackfiber

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?
middleBrick dynamically tests authentication endpoints by sending rapid sequential requests (e.g., 100 attempts) from a single IP. It monitors response codes, timing differences, and error message consistency. For Fiber apps, it specifically checks for missing 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?
middleBrick doesn't just check for the presence of rate limit headers; it actively bypasses common misconfigurations. For Fiber apps, it tests if rate limiting is applied per-username/IP combination (not just globally), verifies limits are enforced on 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.