Open Redirect in Fiber
How Open Redirect Manifests in Fiber
Open Redirect vulnerabilities occur when an application accepts a user-controlled URL and redirects the browser to it without proper validation. In Fiber, this commonly appears in two patterns: query parameter-based redirects and path parameter-based redirects. Attackers exploit these to craft phishing URLs that appear to originate from a trusted domain, stealing credentials or session tokens.
Fiber-Specific Attack Pattern 1: Query Parameter Redirect
Fiber's ctx.Query() method retrieves URL query parameters. A typical vulnerable route accepts a redirect or next parameter and passes it directly to ctx.Redirect():
app.Get("/login", func(ctx *fiber.Ctx) error {
redirectURL := ctx.Query("redirect", "/dashboard")
return ctx.Redirect(redirectURL)
})An attacker can send a victim to https://yourapi.com/login?redirect=https://evil.com. The server responds with a Location: https://evil.com header, redirecting the user to a malicious site after login.
Fiber-Specific Attack Pattern 2: Path Parameter Redirect
Dynamic path parameters (:param) are also vulnerable if used directly in redirects:
app.Get("/go/:url", func(ctx *fiber.Ctx) error {
target := ctx.Params("url")
return ctx.Redirect(target)
})Visiting https://yourapi.com/go/https://evil.com triggers an external redirect. Fiber's router automatically decodes URL-encoded values, so an attacker can include schemes like //evil.com (protocol-relative) or even JavaScript payloads (javascript:alert(1)) if the client interprets them.
Why Fiber is Susceptible
Fiber's ctx.Redirect() and ctx.RedirectStatus() methods do not perform any validation on the target URL. They simply set the Location header. This design assumes the developer has validated the input, which is often overlooked. The vulnerability is not in Fiber itself but in how its convenient redirect helpers are used without sanitization.
Fiber-Specific Detection
Manual Code Review
Search your Fiber codebase for ctx.Redirect and ctx.RedirectStatus. For each occurrence, trace the source of the URL argument. If it comes from ctx.Query(), ctx.Params(), ctx.Get() (headers), or any user-influenced input, it is potentially vulnerable. Example red flags:
ctx.Redirect(ctx.Query("redirect"))ctx.RedirectStatus(301, ctx.Params("url"))
Dynamic Testing
Manually test endpoints by appending common redirect parameters (redirect, url, next, return) with an external URL (e.g., https://attacker.com). Use a tool like curl -i to inspect the Location header:
curl -i "https://yourapi.com/login?redirect=https://attacker.com"If the response includes Location: https://attacker.com (or a protocol-relative //attacker.com), the endpoint is vulnerable.
Scanning with middleBrick
middleBrick's Input Validation check includes Open Redirect detection. Submit your Fiber API endpoint to the middleBrick dashboard or use the middlebrick CLI:
middlebrick scan https://yourapi.commiddleBrick automatically probes common redirect parameters and analyzes the Location header in responses. It flags any redirect to an external domain as a finding under the Input Validation category, with severity based on the redirect's context (e.g., post-login redirects are higher risk). The report includes the exact request that triggered the redirect and remediation guidance specific to Fiber's redirect patterns.
Note: middleBrick performs unauthenticated black-box scanning. Vulnerabilities requiring authentication may require additional setup in your Pro plan's continuous monitoring or CI/CD integration.
Fiber-Specific Remediation
The fix is to validate that the redirect target is a relative path (same-origin) or an explicitly allowed external domain. Fiber does not provide a built-in validator, so implement this using Go's net/url package.
Remediation 1: Allow Only Relative Paths
Parse the URL and ensure it has no host component (i.e., it's a relative path like /dashboard or profile). Also, guard against protocol-relative URLs (//evil.com) and JavaScript schemes (javascript:...):
app.Get("/login", func(ctx *fiber.Ctx) error {
redirectURL := ctx.Query("redirect", "/dashboard")
// Parse the URL
u, err := url.Parse(redirectURL)
if err != nil || u.Host != "" || u.Scheme != "" {
// Invalid or absolute URL: redirect to safe default
return ctx.Redirect("/dashboard")
}
// Optional: Ensure path starts with '/' to prevent relative path tricks
if !strings.HasPrefix(u.Path, "/") {
return ctx.Redirect("/dashboard")
}
return ctx.Redirect(redirectURL)
})Remediation 2: Allowlist Specific Paths
For tighter control, maintain an allowlist of safe redirect paths within your application:
var allowedRedirects = map[string]bool{
"/dashboard": true,
"/profile": true,
"/settings": true,
}
app.Get("/login", func(ctx *fiber.Ctx) error {
redirectURL := ctx.Query("redirect", "/dashboard")
if !allowedRedirects[redirectURL] {
return ctx.Redirect("/dashboard")
}
return ctx.Redirect(redirectURL)
})Remediation 3: Use a Dedicated Library
Consider using a validation library like github.com/go-playground/validator/v10 for complex rules, though for simple redirects, the net/url approach is sufficient.
Important: Always set a safe default redirect (e.g., /dashboard) when validation fails. Never reflect the invalid input back to the user in error messages, as this can aid attackers in mapping parameters.
After applying fixes, re-scan with middleBrick to confirm the Input Validation score improves and the Open Redirect finding is resolved.
Frequently Asked Questions
How does Open Redirect in Fiber differ from other Go frameworks like Gin or Echo?
ctx.Redirect() is a single method that sets status 302 by default, while Gin uses c.Redirect() and Echo uses c.Redirect() with explicit status. The core issue—untrusted input reaching the Location header—remains the same. Remediation requires identical validation logic using net/url.Parse regardless of framework.