Path Traversal in Gorilla Mux with Dynamodb
Path Traversal in Gorilla Mux with Dynamodb — how this specific combination creates or exposes the vulnerability
Path Traversal in a Gorilla Mux service that uses DynamoDB typically occurs when an attacker can control path parameters that are used both for routing and for constructing DynamoDB requests. Gorilla Mux is a URL router and matcher; it does not validate or sanitize parameter values beyond pattern matching. If your route defines a placeholder such as {id} or {fileName} and that value is directly interpolated into a DynamoDB operation (e.g., used as a key attribute or part of a condition), the API may read or return unintended items, effectively performing directory-like traversal through logical data keys.
Consider an endpoint defined with Gorilla Mux to fetch user documents by ID:
r := mux.NewRouter()
r.HandleFunc("/docs/{fileName}", getDocument).Methods("GET")
If getDocument uses the fileName parameter directly to query DynamoDB without validation, an attacker can traverse logical paths such as /docs/../secrets/config. While Gorilla Mux will match the pattern and extract the value as secrets/config, the application may construct a DynamoDB GetItem or Query input using this value as a key or filter, exposing or overwriting data outside the intended scope.
DynamoDB itself does not have a filesystem path concept, but logical traversal manifests as unauthorized access across partition key and sort key boundaries. For example, if the service uses the extracted fileName as the partition key (or part of it), an attacker can access items belonging to other users or services. Unsafe use of expressions like Key("PK", N(123+fileName)) or concatenating user input into key names enables traversal across logical partitions. Additionally, if the application uses DynamoDB Scan with a FilterExpression that incorporates the attacker-controlled value, traversal can lead to data exposure beyond the intended scope.
Another common pattern is exposing internal key structure through error messages or inconsistent handling. For instance, failing to validate that the provided key belongs to the requesting user’s partition allows horizontal privilege escalation across logically related data. This is especially risky when combined with insufficient authorization checks after data retrieval, where the API returns the item without verifying ownership or access rights.
In secure designs, path parameters must be validated and sanitized before being used in any DynamoDB request. Treat Gorilla Mux parameters as untrusted input, and never directly embed them into key attribute values or expression attribute names. Always enforce strict allowlists for acceptable values, and map user-facing identifiers to internal, safe keys.
Dynamodb-Specific Remediation in Gorilla Mux — concrete code fixes
Remediation focuses on strict input validation, canonicalization, and isolating user input from key construction. Below are concrete, safe patterns for a Gorilla Mux endpoint that retrieves items from DynamoDB.
1) Validate and canonicalize path parameters before using them in DynamoDB requests. Use a strict allowlist (e.g., alphanumeric plus limited special safe characters) and reject anything that attempts path traversal.
import "regexp"
var safeName = regexp.MustCompile(`^[a-zA-Z0-9_-]{1,64}$`)
func getDocument(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
fileName := vars["fileName"]
if !safeName.MatchString(fileName) {
http.Error(w, "invalid document identifier", http.StatusBadRequest)
return
}
// safe to use fileName internally
}
2) Map user-facing identifiers to internal keys rather than using raw input as DynamoDB key attributes. This prevents traversal and hides internal schema.
import (
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
)
type DocumentRecord struct {
PK string `json:"pk"`
SK string `json:"sk"`
Data string `json:"data"`
}
func getDocument(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
incoming := vars["fileName"]
if !safeName.MatchString(incoming) {
http.Error(w, "invalid document identifier", http.StatusBadRequest)
return
}
// Map to internal composite key; do not use incoming directly as PK/SK
pk := "USER#" + incoming // example canonicalization
sk := "METADATA"
svc := dynamodb.New(session.New())
out, err := svc.GetItem(&dynamodb.GetItemInput{
TableName: aws.String("Documents"),
Key: map[string]*dynamodb.AttributeValue{
"PK": {S: aws.String(pk)},
"SK": {S: aws.String(sk)},
},
})
if err != nil {
http.Error(w, "server error", http.StatusInternalServerError)
return
}
var rec DocumentRecord
if err := dynamodbattribute.UnmarshalMap(out.Item, &rec); err != nil {
http.Error(w, "server error", http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(rec)
}
3) Avoid expression injection by not concatenating user input into attribute names or expression attribute names. Use placeholders and expression attribute values only.
out, err := svc.Scan(&dynamodb.ScanInput{
TableName: aws.String("Documents"),
FilterExpression: aws.String("begins_with(PK, :prefix)"),
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":prefix": {S: aws.String("USER#" + safeCanonicalName)},
},
})
4) Enforce ownership checks after retrieval. Even if key traversal is prevented, verify that the item belongs to the requester’s scope before returning it.
if !strings.HasPrefix(pk, "USER#"+canonicalUserID) {
http.Error(w, "forbidden", http.StatusForbidden)
return
}
By combining strict validation, key mapping, and explicit authorization, you mitigate Path Traversal risks in a Gorilla Mux + DynamoDB stack.
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 |