Improper limitation of a pathname to a restricted directory ('Path Traversal')
- Rule ID: go_gosec_filesystem_filereadtaint
- Languages: go
- Source: filereadtaint.yml
Description
Constructing file or path information dynamically, especially from user input, poses a significant security risk. If not handled correctly, attackers could manipulate these paths to access or manipulate sensitive files, leading to data breaches or system compromise. It is crucial to ensure that user input is not used directly to interact with the file system, as this can be exploited to perform path traversal attacks.
Remediations
To mitigate the risks associated with dynamic file path construction from user inputs, apply the following best practices:
✅ Hash or Replace User Input
When dealing with user input for file operations, hash the input or replace it with a system-generated unique identifier to prevent path manipulation.
✅ Use filepath.Base
Extract only the filename from the path, ignoring any directory information, to avoid directory traversal vulnerabilities.
✅ Validate Paths Before Use
Always perform validation on the resolved paths before accessing files to ensure they are within the expected directory.
import (
"crypto/rand"
"encoding/hex"
"io"
"log"
"path/filepath"
"strings"
)
// userData struct holds user-related data with a unique ID for file operations
type userData struct {
id string // Unique identifier for the filename
userFilename string // Original filename from the user, kept for reference
}
// newUserData constructs a new userData instance with a random file ID
func newUserData(userFilename string) userData {
return userData{
id: randomFileID(), // Use a random ID instead of user-provided filename
userFilename: userFilename,
}
}
// randomFileID generates a secure random ID to be used as a filename
func randomFileID() string {
id := make([]byte, 16)
if _, err := io.ReadFull(rand.Reader, id); err != nil {
log.Fatal(err)
}
return hex.EncodeToString(id)
}
func main() {
// Simulated user input, which may be malicious
data := newUserData("../../possibly/malicious")
// Define a safe base path for file operations
const basePath = "/tmp/"
// Resolve the full path using the safe base path and the random ID
resolvedPath, err := filepath.Join(basePath, filepath.Base(data.id))
if err != nil {
log.Fatal(err)
}
// Ensure the resolved path is within our designated base path
if !strings.HasPrefix(resolvedPath, basePath) {
log.Fatal("The resolved path does not start with the expected base path")
}
// The file can now be safely accessed using resolvedPath
// Further file processing code would go here
}
Resources
Associated CWE
OWASP Top 10
Configuration
To skip this rule during a scan, use the following flag
bearer scan /path/to/your-project/ --skip-rule=go_gosec_filesystem_filereadtaint
To run only this rule during a scan, use the following flag
bearer scan /path/to/your-project/ --only-rule=go_gosec_filesystem_filereadtaint
Ready to take the next step? Learn more about Bearer Cloud.