Path Traversal in Gorilla Mux with Jwt Tokens
Path Traversal in Gorilla Mux with Jwt Tokens — how this specific combination creates or exposes the vulnerability
Path Traversal occurs when user-controlled input used in file paths is not properly validated, allowing an attacker to access files outside the intended directory, for example via sequences like ../. In Gorilla Mux, a common pattern is to define route variables (e.g., /files/{filename}) and use those variables directly in filesystem operations. If the route is wrapped with JWT-based authentication middleware, an attacker may bypass or misuse authorization checks, leading to authenticated Path Traversal. A typical vulnerable setup uses a JWT middleware that extracts claims and attaches them to the request context, but then fails to sanitize the path parameter before joining it with a base directory.
Consider a handler registered with Gorilla Mux where the route includes a file identifier extracted from the URL, and JWT middleware ensures a user is authenticated. If the handler constructs a filesystem path by concatenating a user-supplied filename from the route with a base path, an attacker authenticated with a valid JWT can send a crafted request such as /files/../../../etc/passwd. The JWT token may grant access to the endpoint, but the lack of path sanitization allows directory traversal. This combination is risky because authentication is present (potentially giving a false sense of security), yet the actual file access is not confined to intended directories. The vulnerability is not in JWT validation itself, but in the unchecked use of route parameters in filesystem operations after authentication.
Moreover, if JWT claims include roles or permissions that the application trusts without additional authorization checks for file access, an attacker with a low-privilege token might traverse to sensitive files that the application logic assumes are inaccessible. For example, a token with scope read:files might be used to iterate outside the sandbox. Because Gorilla Mux routes map directly to handler functions, developers must explicitly validate and sanitize path components regardless of the presence of JWT authentication.
Jwt Tokens-Specific Remediation in Gorilla Mux — concrete code fixes
To remediate Path Traversal in Gorilla Mux when using JWT tokens, validate and sanitize all user-controlled path inputs before using them in filesystem operations. Use filepath.Clean and ensure the resolved path remains within a permitted base directory. Do not rely on JWT-based authorization alone to protect file paths; enforce strict allowlists for filenames or use mappings from token claims to permitted resources.
Example of a vulnerable handler:
func fileHandler(baseDir string) http.Handler {
r := mux.NewRouter()
r.HandleFunc("/files/{filename}", func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
filename := vars["filename"]
// Unsafe: directly joining user input
path := filepath.Join(baseDir, filename)
http.ServeFile(w, r, path)
})
// JWT middleware attached elsewhere
return r
}
Fixed version with path validation and JWT claim checks:
func secureFileHandler(baseDir string) http.Handler { r := mux.NewRouter() r.HandleFunc("/files/{filename}", func(w http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) filename := vars["filename"] // Validate filename: allow only alphanumeric, dashes, underscores, and limited extensions if !regexp.MustCompile(`^[a-zA-Z0-9_.-]+\.(txt|pdf|jpg|png)$`).MatchString(filename) { http.Error(w, "invalid filename", http.StatusBadRequest) return } // Ensure the resolved path stays within baseDir resolved, err := filepath.EvalSymlinks(filepath.Clean(filepath.Join(baseDir, filename))) if err != nil { http.Error(w, "invalid file", http.StatusBadRequest) return } if !strings.HasPrefix(resolved, filepath.Clean(baseDir)+string(os.PathSeparator)) && resolved != filepath.Clean(baseDir) { http.Error(w, "access denied", http.StatusForbidden) return } // Optionally inspect JWT claims for additional constraints claims, ok := req.Context().Value("claims").(jwt.MapClaims) if !ok { http.Error(w, "unauthorized", http.StatusUnauthorized) return } // Example: ensure the user is allowed to access only a subdirectory per claim userScope := claims["scope"] if userScope != "admin" && !strings.HasPrefix(resolved, filepath.Clean(baseDir)+"/userdata/") { http.Error(w, "insufficient scope", http.StatusForbidden) return } http.ServeFile(w, req, resolved) }) // Assume JWT middleware sets claims in context return r }When integrating with authentication, always treat route variables as untrusted input. Combine JWT validation with strict path checks to prevent traversal regardless of token validity.
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 |