• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..09-Apr-2021-

LICENSEH A D09-Apr-20211.5 KiB2925

README.mdH A D09-Apr-20212.1 KiB6649

join.goH A D09-Apr-20214.5 KiB13573

vendor.confH A D09-Apr-202129 21

vfs.goH A D09-Apr-20211.7 KiB429

README.md

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