Injection Flaws in Fiber
How Injection Flaws Manifests in Fiber
Injection flaws in Fiber applications typically occur when user-supplied data is incorporated into SQL queries, command execution, or template rendering without proper sanitization. Fiber's design patterns can inadvertently create injection vulnerabilities if developers aren't careful with how they handle request parameters.
A common injection pattern in Fiber involves SQL injection through improper query construction. Consider this vulnerable code:
func getUser(c *fiber.Ctx) error {
id := c.Query("id")
var user User
db.Raw("SELECT * FROM users WHERE id = " + id).Scan(&user)
return c.JSON(user)
}
Here, the query parameter is concatenated directly into the SQL statement. An attacker could supply 1 OR 1=1 to bypass authentication or 1; DROP TABLE users; to execute destructive commands.
Fiber's template rendering system can also introduce injection vulnerabilities. When using HTML templates with user input:
func renderProfile(c *fiber.Ctx) error {
name := c.Query("name")
return c.Render("profile", fiber.Map{"name": name})
}
If the template doesn't properly escape output, this could lead to Cross-Site Scripting (XSS) injection. The template might contain {{name}} which, if not escaped, would execute any HTML/JavaScript the attacker provides.
Command injection is another risk when Fiber handlers execute system commands with user input:
func getFile(c *fiber.Ctx) error {
filename := c.Query("file")
output, _ := exec.Command("cat", "/data/"+filename).Output()
return c.SendString(string(output))
}
An attacker could supply file.txt; rm -rf / to execute arbitrary commands on the server.
Fiber-Specific Detection
Detecting injection flaws in Fiber applications requires both manual code review and automated scanning. middleBrick's black-box scanning approach is particularly effective for identifying injection vulnerabilities without requiring access to source code.
When scanning a Fiber API endpoint, middleBrick tests for SQL injection by attempting to:
- Break out of string literals using single quotes
- Comment out trailing SQL with
--or# - Use SQL boolean logic (
OR 1=1,AND 1=0) - Attempt UNION-based queries to extract data
For command injection detection, middleBrick sends payloads like:
; echo "vulnerable"
| echo "vulnerable"
$(echo vulnerable)
The scanner analyzes responses for indicators of successful injection, such as unexpected output or error messages containing SQL syntax.
Fiber's middleware architecture can help detect injection attempts. A security middleware could log suspicious patterns:
func injectionDetectionMiddleware() fiber.Handler {
return func(c *fiber.Ctx) error {
if strings.Contains(c.Query("q"), "' OR ") ||
strings.Contains(c.FormValue("data"), "; rm -rf") {
log.Printf("Suspicious input detected: %v", c.Query())
}
return c.Next()
}
}
For template injection, middleBrick checks if user input appears in HTML responses without proper escaping, looking for script tags or HTML entities in the output.
Fiber-Specific Remediation
Remediating injection flaws in Fiber applications requires using the framework's built-in features and Go's security best practices. For SQL injection, always use parameterized queries:
func getUserSafe(c *fiber.Ctx) error {
id := c.Query("id")
var user User
db.Raw("SELECT * FROM users WHERE id = ?", id).Scan(&user)
return c.JSON(user)
}
The ? placeholder prevents the input from being interpreted as SQL code.
For template rendering, use Fiber's built-in escaping:
func renderSafeProfile(c *fiber.Ctx) error {
name := c.Query("name")
return c.Render("profile", fiber.Map{"name": html.EscapeString(name)})
}
Alternatively, use Fiber's default template escaping by configuring the template engine to auto-escape:
func setupTemplates(app *fiber.App) {
engine := &amber.Engine{}
engine.Funcs(template.FuncMap{"safe": func(s string) template.HTML {
return template.HTML(s)
}})
app.Settings.TemplateEngine = engine
app.Settings.TemplateData = fiber.Map{}
}
For command injection prevention, avoid shell execution entirely when possible:
func getFileSafe(c *fiber.Ctx) error {
filename := c.Query("file")
// Validate filename is alphanumeric and within allowed directory
if matched, _ := regexp.MatchString(`^[a-zA-Z0-9_-]+\.txt$`, filename); !matched {
return c.Status(400).SendString("Invalid filename")
}
output, err := os.ReadFile(filepath.Join("/data", filename))
if err != nil {
return c.Status(404).SendString("File not found")
}
return c.Send(output)
}
Implement input validation middleware for all Fiber endpoints:
func validateInput(next fiber.Handler) fiber.Handler {
return func(c *fiber.Ctx) error {
// Reject requests containing suspicious patterns
for _, v := range c.Query() {
if strings.Contains(v, "' OR ") || strings.Contains(v, "; DROP ") {
return c.Status(400).SendString("Invalid input")
}
}
return next(c)
}
}
// Use in app setup
app.Use(validateInput())