Path Traversal in Gorilla Mux with Firestore
Path Traversal in Gorilla Mux with Firestore — how this specific combination creates or exposes the vulnerability
Path Traversal occurs when an attacker manipulates a file or document identifier to access resources outside the intended directory or collection. In a web service built with Gorilla Mux and Google Cloud Firestore, this typically arises when an HTTP route parameter (for example, a document ID or a path-based lookup) is used directly to construct Firestore document references without validation or sanitization.
Gorilla Mux provides route variables such as {id} or {docPath} that are easy to bind into application logic. If these variables are passed to Firestore using the client’s Doc method without ensuring they refer only to allowed documents or collections, an attacker can supply encoded traversal sequences like ../../../sensitive to reach parent paths in the logical document hierarchy. Firestore does not have a traditional filesystem path, but logical paths can still traverse into unintended collections or documents if the input is not constrained.
Another common pattern is using user input to determine which Firestore collection or document to query. For example, a handler might read a resource type and an identifier from the URL and directly concatenate them into a document path. This can expose data that should be isolated by tenant, project, or user boundaries. Even though Firestore enforces security rules, those rules should not be relied upon as the sole defense; the application layer must ensure that identifiers are canonical and scoped correctly before forming any document reference.
Because middleBrick scans unauthenticated attack surfaces, it can detect endpoints that accept path parameters and then use them in Firestore document lookups without proper validation. Its checks include input validation and authorization, mapping findings to the OWASP API Top 10 and relevant compliance frameworks. The scanner does not exploit or modify data; it reports the exposed risk and provides remediation guidance.
Firestore-Specific Remediation in Gorilla Mux — concrete code fixes
To mitigate path traversal in Gorilla Mux when working with Firestore, validate and sanitize all route variables before constructing Firestore document references. Use strict allowlists for identifiers and avoid directly concatenating user input into document paths.
Example: Unsafe handler (vulnerable)
// DO NOT USE: vulnerable to path traversal via docPath
func docHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
docPath := vars["docPath"] // e.g., users/123/private
ctx := context.Background()
client, _ := firestore.NewClient(ctx, "my-project")
docRef := client.Doc(docPath) // attacker can set docPath to "../../../admin/config"
doc, err := docRef.Get(ctx)
// ... handle response
}
Example: Safe handler with validation and canonicalization
func docHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
userID := vars["userID"]
docName := vars["docName"]
// Validate userID is a valid UID pattern
if !regexp.MustCompile(`^[a-zA-Z0-9_-]{1,64}$`).MatchString(userID) {
http.Error(w, "invalid user identifier", http.StatusBadRequest)
return
}
// Validate docName against an allowlist
allowedDocs := map[string]bool{"profile": true, "settings": true}
if !allowedDocs[docName] {
http.Error(w, "document not allowed", http.StatusBadRequest)
return
}
// Canonicalize the path; do not allow traversal sequences
docRef := client.Doc(fmt.Sprintf("users/%s/%s", userID, docName))
ctx := context.Background()
doc, err := docRef.Get(ctx)
if err != nil {
http.Error(w, "unable to retrieve document", http.StatusInternalServerError)
return
}
// ... return safe data
}
Example: Collection-scoped access with Firestore security rules awareness
// Assume tenantID is validated and comes from a trusted source (e.g., JWT)
func queryTenantData(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
tenantID := vars["tenantID"]
// Strict pattern to avoid injection
if !regexp.MustCompile(`^[a-f0-9-]+$`).MatchString(tenantID) {
http.Error(w, "invalid tenant", http.StatusBadRequest)
return
}
ctx := context.Background()
client, _ := firestore.NewClient(ctx, "my-project")
// Scope to a collection under the tenant
collRef := client.Collection("tenants").Doc(tenantID).Collection("records")
iter := collRef.Documents(ctx)
defer iter.Stop()
for {
doc, err := iter.Next()
if err == iterator.Done {
break
}
if err != nil {
http.Error(w, "query failed", http.StatusInternalServerError)
return
}
// process doc.Data()
}
}
Additional defensive practices include: - Using Firestore security rules to enforce tenant isolation, but not relying on them exclusively. - Avoiding dynamic collection names derived from user input. - Logging rejected attempts for audit trails, while ensuring logs do not leak sensitive data.
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 |