diff --git a/go/ql/src/Security/CWE-022/TaintedPath.qhelp b/go/ql/src/Security/CWE-022/TaintedPath.qhelp index 94edec4e4f4b..ab9b3be41158 100644 --- a/go/ql/src/Security/CWE-022/TaintedPath.qhelp +++ b/go/ql/src/Security/CWE-022/TaintedPath.qhelp @@ -38,6 +38,20 @@ result in the string "../" if only "../" sequences are removed. Finally, the simplest (but most restrictive) option is to use an allow list of safe patterns and make sure that the user input matches one of these patterns.

+ +

+Sanitizer functions from the Go standard library: +

+

+The Go standard library provides several functions that can help sanitize paths: +

+ @@ -71,6 +85,13 @@ that the resulting path is still within it.

+Using Go standard library sanitizers: +

+

+You can also use Go's built-in path validation functions for additional safety: +

+ +

Note that /home/user is just an example, you should replace it with the actual safe directory in your application. Also, while in this example the path of the safe directory is absolute, this may not always be the case, and you may need to resolve it diff --git a/go/ql/src/Security/CWE-022/TaintedPathSanitizers.go b/go/ql/src/Security/CWE-022/TaintedPathSanitizers.go new file mode 100644 index 000000000000..6c2696911a08 --- /dev/null +++ b/go/ql/src/Security/CWE-022/TaintedPathSanitizers.go @@ -0,0 +1,56 @@ +package main + +import ( + "net/http" + "os" + "path/filepath" + "strings" +) + +func handleFileWithSanitizers(w http.ResponseWriter, r *http.Request) { + userPath := r.URL.Query().Get("file") + safeDir := "/home/user/documents" + + // Method 1: Using filepath.IsLocal to validate the path is local + if !filepath.IsLocal(userPath) { + http.Error(w, "Invalid path: must be local", http.StatusBadRequest) + return + } + + // Method 2: Using strings.Contains to check for path traversal sequences + if strings.Contains(userPath, "..") { + http.Error(w, "Invalid path: contains path traversal", http.StatusBadRequest) + return + } + + // Method 3: Using filepath.Rel to ensure path is within safe directory + relPath, err := filepath.Rel(safeDir, filepath.Join(safeDir, userPath)) + if err != nil || strings.HasPrefix(relPath, "..") { + http.Error(w, "Invalid path: outside safe directory", http.StatusBadRequest) + return + } + + // Method 4: Using filepath.Clean with absolute prefix for normalization + cleanPath := filepath.Clean("/" + userPath) + if strings.Contains(cleanPath, "..") { + http.Error(w, "Invalid path after normalization", http.StatusBadRequest) + return + } + + // Method 5: Using strings.HasPrefix for additional validation + finalPath := filepath.Join(safeDir, userPath) + if !strings.HasPrefix(finalPath, safeDir) { + http.Error(w, "Invalid path: must be within safe directory", http.StatusBadRequest) + return + } + + // Safe to open file + file, err := os.Open(finalPath) + if err != nil { + http.Error(w, "File not found", http.StatusNotFound) + return + } + defer file.Close() + + // Process file... +}