Description
Currently the standard library does not provide any "simple" helper to avoid filepath.Join
path traversals. As a result, I've had to include similar functions in several projects:
-
Docker has several implementations that are pretty similar.
-
runC / libcontainer has one which is used by several other projects.
The intention of this addition is to make it much easier for Go developers to do "the right thing" when it comes to path safety. Note that the above examples (intentionally) only operate lexically, but SecureJoin
should operate on the actual filesystem in order to earn the "secure" label.
Docker already has an implementation of symlink evaluation within a root filesystem (called FollowSymlinkInScope
), which safely resolves all symlink components of a path as though the process was in a chroot
. The algorithm used by that code could be used to implement SecureJoin
.
There are many Go programs that really need this sort of helper function:
-
Any container runtime or program that interacts with container root filesystems. If a user controls the root filesystem, they can trick said runtime into evaluating files on the host unless the program implements some sort of rooted evaluation of a path.
-
Users of
archive/tar
where the archive might be malicious need to be careful of cases where an archive entry's name contains a symbolic link controlled by the archive. Unless the archive's paths are securely joined with the extraction point of the archive, it's possible that such an archive will cause thearchive/tar
user to access files outside the extraction point of the archive. -
ftp
servers or other file sharing servers that have to operate on user controlled directories. If a path contains user-controlled symlinks they may be able to access paths outside of the context that a file sharing server may expect. -
Web servers with user-defined paths have similar issues.
With helper methods like these in the standard library, recent issues like minio
's path traversal vuln would hopefully happen less often. And with a name like SecureJoin
one would hope that users will be incentivised to use this method (and may in fact become aware of the security issues of using filepath.Join
with user-controlled path components).
One important thing to note is that symlink races will be out-of-scope for SecureJoin
, simply because it's not possible to solve that problem within a standard library package.
If you'd like I could create a new project that contains just these two helper function implementations so they can be better reviewed for inclusion before I create a PR on gerrit.