Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uncontrolled data used in path expression #407

Open
avelino opened this issue Sep 1, 2020 · 0 comments
Open

Uncontrolled data used in path expression #407

avelino opened this issue Sep 1, 2020 · 0 comments

Comments

@avelino
Copy link
Member

avelino commented Sep 1, 2020

if _, err = os.Stat(script); os.IsNotExist(err) {

if script receive path back / to the root of the system, how was os.Stat behave?


Accessing files using paths constructed from user-controlled data can allow an attacker to access unexpected resources. This can result in sensitive information being revealed or deleted, or an attacker being able to influence behavior by modifying unexpected files.

Recommendation

Validate user input before using it to construct a file path, either using an off-the-shelf library or by performing custom validation.

Ideally, follow these rules:

  • Do not allow more than a single "." character.
  • Do not allow directory separators such as "/" or "" (depending on the file system).
  • Do not rely on simply replacing problematic sequences such as "../". For example, after applying this filter to ".../...//", the resulting string would still be "../".
  • Use an allowlist of known good patterns.

Example

In the first example, a file name is read from an HTTP request and then used to access a file. However, a malicious user could enter a file name which is an absolute path, such as "/etc/passwd".

In the second example, it appears that the user is restricted to opening a file within the "user" home directory. However, a malicious user could enter a file name containing special characters. For example, the string "../../etc/passwd" will result in the code reading the file located at "/home/user/../../etc/passwd", which is the system's password file. This file would then be sent back to the user, giving them access to password information.

package main

import (
	"io/ioutil"
	"net/http"
	"path/filepath"
)

func handler(w http.ResponseWriter, r *http.Request) {
	path := r.URL.Query()["path"][0]

	// BAD: This could read any file on the file system
	data, _ := ioutil.ReadFile(path)
	w.Write(data)

	// BAD: This could still read any file on the file system
	data, _ = ioutil.ReadFile(filepath.Join("/home/user/", path))
	w.Write(data)
}

References

  • Common Weakness Enumeration: CWE-22
  • Common Weakness Enumeration: CWE-23
  • Common Weakness Enumeration: CWE-36
  • Common Weakness Enumeration: CWE-73
  • Common Weakness Enumeration: CWE-99
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant