Link Search Menu Expand Document

Unrestricted File Download in Go Lang

Vulnerable Example

The following example is a vulnerable code example that serves files from a directory in an unsecure way:

const ROOT string = "/path/to/root/%s"

func getFileByName(file_name string) string {
    path := fmt.Sprintf(ROOT, file_name)

    buffer, err := ioutil.ReadFile(path)
    if err != nil {
        return name
    }

    return buffer
}

If file_name is controlled by the user, it is possible to retrieve arbitrary files in the filesystem by means of ../, for example:

getFileByName("../../../etc/passwd")

This results in the absolute path /path/to/root/../../../etc/passwd, and its canonicalized form /etc/passwd. To remediate the vulnerability, the path variable can be safely built as follows:

path := fmt.Sprintf(ROOT, path.Base(file_name))

The previous attack would result in reading the /path/to/root/passwd file.

Prevention

Ensure the use of user-provided values, which can be used to escape the designed directory by means of ../ is avoided. For example, the path.Base method can be used to extract the base component of a path.

References

Owasp - Path Traversal