---
title: Use Internal Data For File Paths
impact: CRITICAL
impactDescription: prevents path traversal attacks
tags: file-path, path-traversal, lfi, input-validation, security
---

## Use Internal Data For File Paths

Never construct file paths using user input directly. Path traversal attacks can access any file on the system.

**Incorrect (user-controlled paths):**

```go
// Path traversal vulnerability
func DownloadHandler(w http.ResponseWriter, r *http.Request) {
    filename := r.URL.Query().Get("file")
    http.ServeFile(w, r, "/uploads/"+filename)
    // Attacker: ?file=../../../etc/passwd
}
```

**Correct (validated internal paths):**

```go
import (
    "path/filepath"
    "strings"
)

func DownloadHandler(w http.ResponseWriter, r *http.Request) {
    filename := r.URL.Query().Get("file")
    
    // 1. Sanitize: get only the filename
    safeName := filepath.Base(filename)
    
    // 2. Validate against allowlist (e.g., from DB)
    if !isUserFile(r.Context().Value("userId").(string), safeName) {
        http.Error(w, "File not found", 404)
        return
    }
    
    // 3. Construct absolute path and verify prefix
    uploadDir := "/abs/path/to/uploads"
    finalPath := filepath.Join(uploadDir, safeName)
    
    if !strings.HasPrefix(finalPath, uploadDir) {
        http.Error(w, "Invalid path", 400)
        return
    }
    
    http.ServeFile(w, r, finalPath)
}
```

**Tools:** `filepath.Base`, `filepath.Join`, `gosec` (G304)
