Path Traversal in Echo Go with Firestore
Path Traversal in Echo Go with Firestore — how this specific combination creates or exposes the vulnerability
Path Traversal occurs when an API uses attacker-controlled input to build file or document paths without proper validation, allowing access to files or resources outside the intended directory or collection. In an Echo Go service that uses Firestore, this typically arises when a user-supplied identifier (such as a document ID or a path segment) is directly concatenated into Firestore document references or queries without normalization or strict allowlisting.
Consider an endpoint that retrieves user profile data by ID: GET /profiles/{userID}. If the handler passes userID directly into a Firestore document path, a request for /profiles/../../../secrets/config can result in a reference that resolves outside the intended profiles collection. While Firestore itself does not use a traditional filesystem path model, the equivalent risk is referencing documents or collections outside the expected scope. For example, a Firestore reference built from unchecked input could point to sensitive documents such as users/../../admin/settings if the input is not validated.
When combined with Firestore’s real-time listeners and flexible querying, an attacker may leverage traversal attempts to probe for accessible collections or documents, especially if security rules are misconfigured. Firestore rules that rely on request.resource.data without validating the document path can inadvertently permit reads or writes to unintended locations. Insecure rule logic such as allowing write access if request.resource.data.userId == request.auth.uid may still permit traversal within the user’s own subtree, but if the path is manipulated, the rule might not apply as intended.
In an automated scan using middleBrick, such endpoints would be flagged during the BOLA/IDOR and Input Validation checks. The scanner sends crafted inputs like ../../admin in place of path parameters and inspectulates Firestore access patterns and response behaviors. If the API returns data or does not enforce strict path scoping, middleBrick highlights the issue with severity and provides remediation guidance tied to the specific endpoint and Firestore interaction.
Additionally, Firestore’s use of structured paths means that traversal-like behavior can also manifest through array indices or map keys if input is not properly constrained. For example, an endpoint that dynamically builds a document path using user input without sanitization could expose nested collections such as organizations/{orgID}/users/{userID}/private, where orgID or userID originate from the request. middleBrick’s unauthenticated attack surface testing includes these scenarios to detect unintended data exposure before an attacker does.
Firestore-Specific Remediation in Echo Go — concrete code fixes
To mitigate Path Traversal in Echo Go with Firestore, validate and sanitize all user input used to construct document references or queries. Use allowlists for known-safe values and enforce strict schema checks before interacting with Firestore.
Secure Document Reference Construction
Instead of concatenating user input directly into a document path, parse and validate the input against expected patterns. For document IDs, use regular expressions to allow only alphanumeric characters and hyphens. Then, explicitly build the reference using the Firestore Go SDK.
import (
"context"
"regexp"
"net/http"
"github.com/labstack/echo/v4"
"cloud.google.com/go/firestore"
)
func getProfile(c echo.Context) error {
userID := c.Param("userID")
matched, err := regexp.MatchString(`^[a-zA-Z0-9_-]{1,100}$`, userID)
if err != nil || !matched {
return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid user identifier"})
}
ctx := c.Request().Context()
client, err := firestore.NewClient(ctx, "your-project-id")
if err != nil {
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "failed to create client"})
}
defer client.Close()
docRef := client.Collection("profiles").Doc(userID)
var profile map[string]interface{}
if err := docRef.Get(ctx, &profile); err != nil {
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "failed to fetch profile"})
}
return c.JSON(http.StatusOK, profile)
}
Strict Query Scoping with Field Validation
When querying nested collections, ensure that parent document IDs are also validated and not derived from untrusted input. Use Firestore queries that explicitly scope to a known collection and document structure.
func getUserData(c echo.Context) error {
orgID := c.Param("orgID")
userID := c.Param("userID")
if !isValidID(orgID) || !isValidID(userID) {
return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid identifiers"})
}
ctx := c.Request().Context()
client, err := firestore.NewClient(ctx, "your-project-id")
if err != nil {
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "client creation failed"})
}
defer client.Close()
iter := client.Collection("organizations").Doc(orgID).Collection("users").Where(firestore.DocumentID, "==", userID).Documents(ctx)
defer iter.Stop()
if doc, err := iter.Next(); err == iterator.Done {
return c.JSON(http.StatusNotFound, map[string]string{"error": "user not found"})
} else if err != nil {
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "query error"})
} else {
return c.JSON(http.StatusOK, doc.Data())
}
}
func isValidID(id string) bool {
matched, _ := regexp.MatchString(`^[a-zA-Z0-9_-]{1,50}$`, id)
return matched
}
Firestore Security Rules Alignment
Complement Go-level validation with Firestore security rules that restrict reads and writes to expected paths. Rules should validate not only data content but also document path structure where possible.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /profiles/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
match /organizations/{orgId}/users/{userID} {
allow read, write: if request.auth != null && request.auth.uid == userId && orgIdMatchesSomeCondition(orgId);
}
}
}
By combining strict input validation, explicit path construction, and aligned security rules, the risk of Path Traversal in an Echo Go and Firestore stack is significantly reduced. middleBrick can verify these controls by testing with crafted traversal inputs and inspecting whether the API enforces expected scoping.
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |