flawopen.com/path-traversal/Go
How filepath.Join in Go fails to restrict file boundaries, and how to enforce containment using filepath.Clean and filepath.Rel.
एक होटल के कमरे के कार्ड रीडर की कल्पना करें जिसे केवल दूसरी मंजिल के कमरे खोलने चाहिए। यदि कोई मेहमान कीपैड पर '../../master-safe' टाइप करता है, तो असुरक्षित ताला हॉलवे से बाहर निकलकर प्रबंधक की तिजोरी खोल देता है।
Web Application SecurityCWE-918.CWE-918CWE-918): Standard Common Weakness Enumeration classification for path-traversal-go.Defense-in-Depthएंडपॉइंट HTTP पैरामीटर के माध्यम से उपयोगकर्ता द्वारा प्रदान किया गया फ़ाइल नाम स्वीकार करता है।
हमलावर फ़ाइल नाम में '../' या '..%2f' जैसे रिलेटिव डायरेक्टरी ट्रैवर्सल सीक्वेंस डालता है।
बैकएंड कैनोनिकल पाथ को सत्यापित किए बिना बेस डायरेक्टरी के साथ पाथ को जोड़ देता है।
सर्वर सिस्टम की संवेदनशील फ़ाइलें (/etc/passwd, पासवर्ड या कुंजियाँ) पढ़कर हमलावर को भेज देता है।
// VULNERABLE: filepath.Join does not prevent directory breakout
package main
import (
"net/http"
"os"
"path/filepath"
)
func downloadHandler(w http.ResponseWriter, r *http.Request) {
filename := r.URL.Query().Get("file")
baseDir := "/var/app/public/files"
// Attacker input: "../../etc/shadow"
targetPath := filepath.Join(baseDir, filename)
data, err := os.ReadFile(targetPath)
if err != nil {
http.NotFound(w, r)
return
}
w.Write(data)
}
// HARDENED: Use filepath.Rel to verify target is strictly inside baseDir
package main
import (
"net/http"
"os"
"path/filepath"
"strings"
)
func downloadHandler(w http.ResponseWriter, r *http.Request) {
filename := r.URL.Query().Get("file")
baseDir := "/var/app/public/files"
// 1. Resolve absolute paths
absBase, err := filepath.Abs(baseDir)
if err != nil {
http.Error(w, "Server error", http.StatusInternalServerError)
return
}
absTarget := filepath.Join(absBase, filepath.Clean("/"+filename))
// 2. Verify relative containment
rel, err := filepath.Rel(absBase, absTarget)
if err != nil || strings.HasPrefix(rel, "..") || rel == "." {
http.Error(w, "Access denied: Path Traversal detected", http.StatusForbidden)
return
}
data, err := os.ReadFile(absTarget)
if err != nil {
http.NotFound(w, r)
return
}
w.Write(data)
}
filepath.Clean()।filepath.Rel() को सत्यापित और जांचें।filepath.EvalSymlinks() where necessary।os.DirFS() which enforce chroot-like root boundaries का उपयोग करें।