1## `filepath-securejoin` ## 2 3[![Build Status](https://travis-ci.org/cyphar/filepath-securejoin.svg?branch=master)](https://travis-ci.org/cyphar/filepath-securejoin) 4 5An implementation of `SecureJoin`, a [candidate for inclusion in the Go 6standard library][go#20126]. The purpose of this function is to be a "secure" 7alternative to `filepath.Join`, and in particular it provides certain 8guarantees that are not provided by `filepath.Join`. 9 10This is the function prototype: 11 12```go 13func SecureJoin(root, unsafePath string) (string, error) 14``` 15 16This library **guarantees** the following: 17 18* If no error is set, the resulting string **must** be a child path of 19 `SecureJoin` and will not contain any symlink path components (they will all 20 be expanded). 21 22* When expanding symlinks, all symlink path components **must** be resolved 23 relative to the provided root. In particular, this can be considered a 24 userspace implementation of how `chroot(2)` operates on file paths. Note that 25 these symlinks will **not** be expanded lexically (`filepath.Clean` is not 26 called on the input before processing). 27 28* Non-existant path components are unaffected by `SecureJoin` (similar to 29 `filepath.EvalSymlinks`'s semantics). 30 31* The returned path will always be `filepath.Clean`ed and thus not contain any 32 `..` components. 33 34A (trivial) implementation of this function on GNU/Linux systems could be done 35with the following (note that this requires root privileges and is far more 36opaque than the implementation in this library, and also requires that 37`readlink` is inside the `root` path): 38 39```go 40package securejoin 41 42import ( 43 "os/exec" 44 "path/filepath" 45) 46 47func SecureJoin(root, unsafePath string) (string, error) { 48 unsafePath = string(filepath.Separator) + unsafePath 49 cmd := exec.Command("chroot", root, 50 "readlink", "--canonicalize-missing", "--no-newline", unsafePath) 51 output, err := cmd.CombinedOutput() 52 if err != nil { 53 return "", err 54 } 55 expanded := string(output) 56 return filepath.Join(root, expanded), nil 57} 58``` 59 60[go#20126]: https://github.com/golang/go/issues/20126 61 62### License ### 63 64The license of this project is the same as Go, which is a BSD 3-clause license 65available in the `LICENSE` file. 66