Insecure File Management
Fixing Path Traversals
About Path Traversal
What is Path Traversal?
Path traversal, also known as directory traversal, is a type of security vulnerability that allows an attacker to access files or directories outside the web root directory of a web application. This vulnerability occurs when a web application does not properly validate user input or user-controlled data, such as file names or paths, and allows directory traversal sequences to be passed through the input.
Check out this video for a high-level explanation:
What is the impact of Path Traversal?
Path Traversal can lead to unauthorized access to sensitive files and data on a server or application. This can include files containing passwords, user data, or other confidential information.
An attacker who successfully exploits a Path Traversal vulnerability can gain access to sensitive data, modify or delete files, and potentially execute arbitrary code or perform other malicious actions.
This can lead to a variety of security incidents, such as data breaches, theft of intellectual property, or disruption of services.
The impact of a Path Traversal vulnerability can vary depending on the nature of the files and data that are accessed, as well as the specific context of the system or application being targeted.
In some cases, a Path Traversal attack may have little impact beyond revealing the existence of certain files, while in other cases, it can have severe consequences for the confidentiality, integrity, and availability of the system or application.
How to prevent Path Traversal?
To prevent Path Traversal vulnerabilities, it is important to properly validate and sanitize user input, and to use secure coding practices.
Here are some steps that can help prevent Path Traversal attacks:
- Validate user input: Always validate and sanitize user input, especially file names and paths. Ensure that user input only contains expected characters and that any special characters are properly escaped or removed.
- Use secure coding practices: Use secure coding practices, such as enforcing strict file permissions and preventing the execution of user-controlled input as code. Use libraries and frameworks that have built-in protection against Path Traversal attacks.
- Use an allow list: Use an allow list of permitted file names or directories and reject any input that does not match the list. This can help prevent unauthorized access to sensitive files and directories.
- Implement access controls: Implement access controls to restrict user access to files and directories based on roles and permissions.
- Use server-side checks: Use server-side checks to verify that any requested file or directory is within the expected range and does not contain any invalid or unexpected characters.
- Monitor and log: Monitor and log all file system access to detect any suspicious activity or attempts to access files or directories outside of the expected range.
By following these steps, you can help prevent Path Traversal vulnerabilities and reduce the risk of unauthorized access to sensitive files and data.
References
Taxonomies
- OWASP Top 10 - A01 Broken Access Control
- CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
- CWE-23: Relative Path Traversal
- CWE-36: Absolute Path Traversal
Explanation & Prevention
- OWASP: Path Traversal
- OWASP: File Upload Cheat Sheet
- OWASP: Input Validation Cheat Sheet
- CAPEC-126: Path Traversal
- WASC-33: Path Traversal
Related CVEs
Training
Category-specific resources:
- Common Weakness Enumeration (CWE-73)
- Checkmarx - Go - Web Application Secure Coding Practices: File Management
Path traversal via User Input Allows Writes to Arbitrary Files
There are many applications in which you would want a user to have the ability to specify a file path to write (e.g. file hosting server). However, to make sure this is a safe operation, file paths must be sanitized before being used.
Not sanitizing, or weakly/insecurely sanitizing a file path provided by a user could allow a user to write to sensitive files in the file system.
Here is an example of what an exploit could look like:
http://my-website.com/get?path=../admins.txt&data=bob
. In this
case, an unsanitized path allows an attacker to overwrite
the list of admins and give himself admin permission.
Even if you cannot control the data written, you can stop a server from running by overwriting important files (such as the executable itself).
To protect against this, sanitize file paths by using the
path
or path/filepath
modules.
Rule-specific references:
Option A: Use FilePath.Base() and Verify Extensions
Go through the issues that GuardRails identified in the PR/MR
A vulnerable example is shown below:
package main
import (
"fmt"
"log"
"net/http"
"os"
)
func main() {
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
// The insecure user input is coming from the title parameter
title := r.URL.Query().Get("title")
// and used to directly open a file.
// By using ../../../ attackers can access any file in any folder
// such as the /etc/passwd file, or files containing sensitive data
f, err := os.Open(title)
if err != nil {
fmt.Printf("Error: %v\n", err)
}
body := make([]byte, 5)
if _, err = f.Read(body); err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Fprintf(w, "%s", body)
})
log.Fatal(http.ListenAndServe(":3000", nil))
}Replace it with the following:
package main
import (
"fmt"
"log"
"net/http"
"os"
"strings"
// Import https://golang.org/pkg/path/filepath/#Base
"path/filepath"
)
// Create function to check for valid extensions
func isValidExtension(ext string) bool {
switch ext {
case
".jpg",
".jpeg",
".png":
return true
}
return false
}
func main() {
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
// We are using filepath.Base to ensure the last element of the
// path is returned.
// https://golang.org/pkg/path/filepath/#Base
title := filepath.Base(r.URL.Query().Get("title"))
// You should also check for the correct file extension
// This is done with https://golang.org/pkg/path/filepath/#Ext
extension := strings.ToLower(filepath.Ext(title))
// Call the function to check for allowed extensions
// and only perform the read action if the extension is as expected
if isValidExtension(extension) {
f, err := os.Open(title)
if err != nil {
fmt.Printf("Error: %v\n", err)
}
body := make([]byte, 5)
if _, err = f.Read(body); err != nil {
fmt.Printf("Error: %v\n", err)
}
fmt.Fprintf(w, "%s", body)
}else{
log.Print("Not permitted file extension was encountered.")
}
})
log.Fatal(http.ListenAndServe(":3000", nil))
}Test it
Ship it 🚢 and relax 🌴
Option B: Don't Store Files Locally
Another option is to store files in the cloud. This way local file inclusion attacks can be prevented. Some of the options are:
Path Traversal allows Reads via User Input
There are many applications in which you would want a user to have the ability to specify a file path to read (e.g. file hosting server). However, to make sure this is a safe operation, file paths must be sanitized before being used.
Not sanitizing, or weakly/insecurely sanitizing a file path provided by a user could allow sensitive files to be read from a machine.
Here is an example of what an exploit could look like:
http://my-website.com/get?path=../sqlite.db
. In this
case, an unsanitized path allows an attacker to read an
SQLite database that is residing on the server.
To protect against this, sanitize file paths by using the
path
or path/filepath
modules.
Rule-specific references:
Option A: Sanitize the Paths
The main solution for this vulnerability is to sanitize the paths.
Locate the vulnerable patterns (example below):
func GetFile(resp http.ResponseWriter, req *http.Request) {
file_path := req.URL.Query().Get("path")
file, err := os.Open(file_path)
if err != nil {
http.Error(resp, "Failed to read file", 404)
}
http.ServeContent(resp, req, file.Name(), time.Now(), file)
}Sanitize the file path (example below):
func GetFile(resp http.ResponseWriter, req *http.Request) {
file_path := req.URL.Query().Get("path")
file_path = path.Clean(file_path)
file, err := os.Open(file_path)
if err != nil {
http.Error(resp, "Failed to read file", 404)
}
http.ServeContent(resp, req, file.Name(), time.Now(), file)
}Test it
Ship it 🚢 and relax 🌴
Fixing Directory Listing
About Directory Listing
What is Directory Listing?
Directory listing is a feature of web servers that allows users to view the contents of a directory on a website. When directory listing is enabled, a user can view a list of all the files and directories that are stored in a particular directory, along with any relevant metadata, such as file size or last modified date.
Directory listing can be useful for users who want to browse the contents of a website or find specific files or information. However, it can also pose a security risk, as it can reveal sensitive information about the files and directories stored on a server.
This can include file names, directory structures, and other metadata that could be used by an attacker to gain access to the server or launch other attacks.
What is the impact of Directory Listing?
Directory listing can reveal sensitive information about the files and directories stored on a server. This information can include file names, directory structures, and other metadata that can be used by attackers to gain unauthorized access to the server or launch other attacks.
For example, directory listing can reveal the location of configuration files, backup files, or other sensitive files that can be used to gain access to a system or application. It can also reveal the location of files containing passwords, user data, or other confidential information, which can be used for identity theft or other malicious activities.
Additionally, directory listing can be used by attackers to map out the structure of a website or application, which can be used to identify potential vulnerabilities and launch other attacks.
This can include cross-site scripting (XSS) attacks, SQL injection attacks, or other types of web application attacks.
How to prevent Directory Listing?
To prevent directory listing, it is recommended to follow these steps:
- Disable directory listing: The easiest way to prevent directory listing is to disable it in the web server configuration. This will prevent users from being able to view the contents of directories on the server.
- Use an index file: If directory listing is disabled, users may still be able to access files in a directory if there is an index file present. By adding an index file, such as index.html or index.php, the server will display that file instead of the directory listing.
- Use access controls: Use access controls to restrict user access to files and directories based on roles and permissions. This can help prevent unauthorized access to sensitive files and directories.
- Secure file and directory permissions: Set secure file and directory permissions to prevent unauthorized access. For example, ensure that files and directories are not writable by everyone and that only authorized users have access.
- Use secure coding practices: Use secure coding practices that prevent unauthorized access to sensitive files and directories. This includes validating and sanitizing user input, avoiding the use of hard-coded credentials, and using secure programming languages and frameworks.
- Use monitoring and logging: Use monitoring and logging to detect and respond to any attempts to access directory listings or other sensitive files and data. This can help identify potential security incidents and enable a timely response.
References
Taxonomies
Related CVEs
Sensitive Directories Exposed via http.Dir
The http.Dir
type allows users to access the specified
directory on a server, typically by using it with the
http.FileServer
function.
However, http.Dir
can be dangerous if it exposes
sensitive directories as users could then access sensitive
information.
Option A: Change the Exposed Directory
This solution entails changing the exposed directory to a less sensitive place.
First, locate the vulnerable pattern (example below):
func RegisterHandlers() {
// ...
http.Handle("/files",
http.FileServer(http.Dir("/"))
)
// ...
}Then, replace the vulnerable pattern with a safe alternative (example below):
func RegisterHandlers() {
// ...
http.Handle("/files",
http.FileServer(http.Dir("/var/www"))
)
// ...
}Test it
Ship it 🚢 and relax 🌴