Zip Slip in Chi with Dynamodb
Zip Slip in Chi with Dynamodb — how this specific combination creates or exposes the vulnerability
Zip Slip is a path traversal vulnerability that occurs when an application constructs file paths from user-supplied input without proper validation. In a Chi-based Go service that interacts with AWS DynamoDB, the risk emerges not from DynamoDB itself, but from how file paths are built before being used to read or write files, potentially bypassing intended directory boundaries. Chi is a lightweight router that encourages explicit route handling, and developers may inadvertently concatenate user input—such as a filename from a URL parameter or JSON body—into filesystem paths used alongside DynamoDB operations, for example, when storing or retrieving object metadata or backups.
Consider a scenario where an endpoint accepts a file identifier and uses it to locate a file on disk while also querying DynamoDB for associated metadata. If the handler uses user input to traverse directories (e.g., ./uploads/ + user-provided name), an attacker can supply sequences like ../../../etc/passwd to escape the intended directory. Even when DynamoDB is used to log or reference file locations, a malicious path can lead to unauthorized file reads or writes on the host system. The vulnerability is not in DynamoDB—AWS managed service—but in the application logic that combines user-controlled input with filesystem operations, especially when such logic is executed in the same request lifecycle as DynamoDB interactions, potentially exposing sensitive files or enabling further compromise.
middleBrick detects such risks in its unauthenticated scan by analyzing OpenAPI specs and runtime behavior, identifying path traversal patterns in endpoints that handle file operations. For a Chi service, this includes tracing parameters used in file paths and observing whether they are sanitized with robust validation (e.g., using path.Clean and ensuring the resolved path remains within a designated directory). The scan does not test DynamoDB internals but focuses on the application layer where insecure path construction occurs, highlighting findings related to Input Validation and Unsafe Consumption checks.
Dynamodb-Specific Remediation in Chi — concrete code fixes
To mitigate Zip Slip in a Chi service using DynamoDB, focus on securely handling user input before any filesystem interaction. Always validate and sanitize paths independently of DynamoDB operations, and avoid using raw user input in file paths. Use Go’s standard library functions to ensure paths remain within allowed directories.
Secure Path Handling Example
Instead of concatenating user input directly, use filepath.Join and filepath.Clean, then verify the final path starts with the intended base directory:
import (
"net/http"
"path/filepath"
"github.com/go-chi/chi/v5"
)
const baseDir = "/safe/uploads"
func secureHandler(w http.ResponseWriter, r *http.Request) {
filename := chi.URLParam(r, "filename")
// Normalize and join paths safely
cleanName := filepath.Clean(filename)
targetPath := filepath.Join(baseDir, cleanName)
// Ensure the resolved path is within baseDir
if rel, err := filepath.Rel(baseDir, targetPath); err != nil || rel == ".." || (len(rel) > 0 && rel[0] == '.') {
http.Error(w, "invalid path", http.StatusBadRequest)
return
}
// Proceed with file operations; DynamoDB interactions remain separate
// e.g., updateDynamoDBMetadata(targetPath)
w.Write([]byte("OK"))
}
DynamoDB Interaction Best Practices
When storing or retrieving metadata in DynamoDB, keep user input separate from filesystem logic. Use DynamoDB attributes to map logical identifiers to stored objects, not raw paths:
import (
"context"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)
type FileRecord struct {
FileID string
SafeName string // stored sanitized name, not user input
}
func getFileRecord(ctx context.Context, client *dynamodb.Client, fileID string) (FileRecord, error) {
out, err := client.GetItem(ctx, &dynamodb.GetItemInput{
TableName: aws.String("FileMetadata"),
Key: map[string]types.AttributeValue{
"FileID": &types.AttributeValueMemberS{Value: fileID},
},
})
if err != nil {
return FileRecord{}, err
}
var rec FileRecord
// Unmarshal logic here
return rec, nil
}
By decoupling user input from filesystem paths and using DynamoDB for logical mapping, you reduce the attack surface. middleBrick’s continuous monitoring (available in the Pro plan) can help detect regressions in path handling across deployments.