Path Traversal in Gorilla Mux with Cockroachdb
Path Traversal in Gorilla Mux with Cockroachdb — how this specific combination creates or exposes the vulnerability
Path Traversal occurs when user-supplied input is used to construct file system paths or, in the context of APIs backed by databases, to dynamically build query identifiers that map to filesystem-like resources. With Gorilla Mux, the risk arises from how route variables are passed into database operations without sufficient validation. Cockroachdb, while robust, does not inherently prevent logical path traversal; it executes SQL as provided. If a handler uses a route parameter such as :fileId to select a record, and that identifier is later concatenated into a filesystem path or used in a dynamic WHERE clause that mirrors directory traversal patterns (e.g., ../), the API can expose sensitive files or enable unauthorized data access.
For example, a route defined as /files/{fileId} might construct a SQL query like SELECT path FROM files WHERE id = $1, but if the application uses the resolved path column to read from disk without canonicalization, an attacker supplying ../../../etc/passwd as fileId (after proper encoding or if the application decodes and trusts the input) could traverse outside the intended directory. Even when Cockroachdb returns a valid row, the application layer must treat the returned path as untrusted. The combination of Gorilla Mux’s flexible variable capture and Cockroachdb’s permissive SQL execution means developers must enforce strict validation and canonicalization before using any data derived from the request to access filesystem resources or construct dynamic queries that could be abused for logical traversal.
Additionally, if the API exposes endpoints that accept filenames or directory fragments as path parameters, and those values are used in dynamic SQL such as SELECT content FROM documents WHERE tenant_id = $1 AND name = $2 with the second parameter derived from user input without normalization, attackers may attempt patterns like ..%2Fsecrets to infer or access other tenants’ data. While Cockroachdb will not interpret .. as a filesystem operator, the application’s logic might, especially if it builds file paths on the client side or uses the database result to serve static assets. Therefore, the vulnerability is not in Cockroachdb itself but in how the application mediates between Gorilla Mux routes, user input, and data usage.
Cockroachdb-Specific Remediation in Gorilla Mux — concrete code fixes
To mitigate Path Traversal when using Gorilla Mux and Cockroachdb, validate and sanitize all route parameters before using them in SQL queries or filesystem operations. Use parameterized queries exclusively to avoid SQL injection, and enforce strict allowlists for identifiers such as filenames or tenant IDs. Below are concrete code examples demonstrating secure patterns.
Secure Handler with Parameterized Query and Input Validation
package main
import (
"context"
"net/http"
"path/filepath"
"regexp"
"strings"
"github.com/gorilla/mux"
"github.com/jackc/pgx/v5/pgxpool"
)
var validID = regexp.MustCompile(`^[a-zA-Z0-9_-]{1,64}$`)
func getFileHandler(pool *pgxpool.Pool) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
fileID := vars["fileId"]
// 1. Validate format with strict allowlist
if !validID.MatchString(fileID) {
http.Error(w, "invalid file identifier", http.StatusBadRequest)
return
}
// 2. Use parameterized query to fetch metadata from Cockroachdb
ctx := r.Context()
var filePath string
err := pool.QueryRow(ctx, "SELECT path FROM files WHERE id = $1", fileID).Scan(&filePath)
if err != nil {
http.Error(w, "file not found", http.StatusNotFound)
return
}
// 3. Canonicalize and restrict to intended base directory
base := "/safe/storage"
resolved := filepath.Join(base, filepath.Clean(filePath))
if !strings.HasPrefix(resolved, base) {
http.Error(w, "path traversal detected", http.StatusForbidden)
return
}
// Proceed to serve the file safely
http.ServeFile(w, r, resolved)
}
}
Parameterized Dynamic Query for Tenant-Specific Data
func getTenantDocumentHandler(pool *pgxpool.Pool) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
tenantInput := vars["tenant"]
docName := vars["doc"]
// Strict allowlist for tenant identifier (e.g., subdomain or UUID)
tenantRe := regexp.MustCompile(`^[a-z0-9]{1,32}$`)
if !tenantRe.MatchString(tenantInput) {
http.Error(w, "invalid tenant", http.StatusBadRequest)
return
}
// Use parameterized query to avoid SQL-based traversal
var content string
err := pool.QueryRow(r.Context(),
"SELECT content FROM documents WHERE tenant_id = $1 AND name = $2",
tenantInput, docName).Scan(&content)
if err != nil {
http.Error(w, "document not found", http.StatusNotFound)
return
}
// Further validate docName if it maps to filesystem paths
safeName := filepath.Base(docName)
// ... use safeName for any filesystem operations
w.Write([]byte(content))
}
}
Key practices include: never concatenate user input into SQL strings, always use $1, $2 placeholders with Cockroachdb, validate inputs against strict patterns, and resolve filesystem paths with filepath.Clean and prefix checks. These steps ensure that Gorilla Mux routes and Cockroachdb queries remain resilient against Path Traversal attempts.
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 |