Xpath Injection in Fiber
How Xpath Injection Manifests in Fiber
XPath injection vulnerabilities in Fiber applications typically arise when user input is directly incorporated into XPath queries without proper sanitization. In Fiber's XML processing workflows, this often occurs when handling SOAP requests, XML-based APIs, or when querying XML databases like eXist-db or BaseX.
// Vulnerable Fiber handler using raw user input
func loginHandler(c *fiber.Ctx) error {
username := c.FormValue("username")
password := c.FormValue("password")
// UNSAFE: Direct string interpolation into XPath
xpathQuery := fmt.Sprintf("/users/user[username='%s' and password='%s']", username, password)
result := executeXPathQuery(xpathQuery) // executes the vulnerable query
if result != nil {
return c.JSON(fiber.Map{"status": "authenticated"})
}
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "invalid credentials"})
}
This pattern is particularly dangerous in Fiber because the framework's middleware chain processes XML requests efficiently, and developers often assume the XML parsing layer provides security. An attacker can exploit this by submitting:
username: ' or '1'='1
password: ' or '1'='1
This transforms the XPath query into:
/users/user[username='' or '1'='1' and password='' or '1'='1']
Which always evaluates to true, bypassing authentication entirely. More sophisticated attacks can extract data:
username: ']/following::*/
password: ' or '1'='1
Or even cause denial of service through computationally expensive queries:
username: ' or 1=1 or starts-with(//user[position() mod 2 = 0]/username, 'a
In Fiber applications, this vulnerability often appears in SOAP API endpoints, XML-RPC handlers, and any middleware that processes XML-based requests before authentication is applied.
Fiber-Specific Detection
Detecting XPath injection in Fiber applications requires examining both the code structure and runtime behavior. middleBrick's black-box scanning approach is particularly effective here because it can probe the actual API endpoints without requiring source code access.
middleBrick scans for XPath injection by testing for:
- Boolean logic injection patterns (OR, AND, NOT operators)
- String termination attempts with single quotes
- XPath function calls like
name(),count(),contains() - Comment injection using
::andcomment() - Union-based attacks attempting to extract multiple data points
The scanner's 12 security checks include specific XPath injection testing that sends payloads like:
' or 1=1 or '
' or contains(name(), 'admin')
' or count(//user) > 0 or '
' or name() = 'user' or '
middleBrick's approach is particularly valuable for Fiber applications because it can test the actual XML processing pipeline that runs in production, catching issues that static analysis might miss. The scanner evaluates responses for timing differences, error messages, and data leakage that indicate successful injection.
For developers working with Fiber, the CLI tool provides immediate feedback:
middlebrick scan https://api.example.com/soap
This returns a security score with specific findings about XPath injection vulnerabilities, including the exact payloads that succeeded and remediation guidance.
Fiber-Specific Remediation
Securing XPath queries in Fiber applications requires parameterized queries or proper input sanitization. The most effective approach uses Go's go-xpath library with parameterized expressions:
import "github.com/antchfx/xpath"
func secureLoginHandler(c *fiber.Ctx) error {
username := c.FormValue("username")
password := c.FormValue("password")
// SAFE: Parameterized XPath query
doc, _ := xpath.ParseDocument(xmlData)
expr, _ := xpath.Compile("/users/user[username=$u and password=$p]")
var result *xpath.Node
err := expr.Evaluate(xpath.Set{"u": username, "p": password}, &result)
if err == nil && result != nil {
return c.JSON(fiber.Map{"status": "authenticated"})
}
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "invalid credentials"})
}
Alternatively, when parameterized queries aren't available, use strict input validation:
import "regexp"
var validUsername = regexp.MustCompile(`^[a-zA-Z0-9_]{3,20}$`)
var validPassword = regexp.MustCompile(`^[a-zA-Z0-9!@#$%^&*()_+]{8,}$`)
func validateInput(username, password string) bool {
return validUsername.MatchString(username) && validPassword.MatchString(password)
}
func loginHandler(c *fiber.Ctx) error {
username := c.FormValue("username")
password := c.FormValue("password")
if !validateInput(username, password) {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "invalid input format"})
}
// Now safe to use in XPath query
xpathQuery := fmt.Sprintf("/users/user[username='%s' and password='%s']", username, password)
result := executeXPathQuery(xpathQuery)
if result != nil {
return c.JSON(fiber.Map{"status": "authenticated"})
}
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "invalid credentials"})
}
For SOAP APIs in Fiber, consider using a middleware that validates XML structure before processing:
func xmlValidationMiddleware(c *fiber.Ctx) error {
if c.Get("Content-Type") == "application/soap+xml" {
body := string(c.Context().RequestBody())
if !isValidXML(body) {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "invalid XML format"})
}
}
return c.Next()
}
// Apply to routes that handle XML
app.Post("/soap", xmlValidationMiddleware, soapHandler)
The key principle is never to trust user input in XPath contexts. Always validate, parameterize, or sanitize before query execution.