diff options
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..3bf9b79 --- /dev/null +++ b/README.md @@ -0,0 +1,61 @@ +## What is `safepath`? + +`safepath` is tiny library written in C, targeting POSIX systems. + +Its core functionality is concentrated in a single function `safepath_check`. + +`safepath_check` performs one function: it takes a filename consisting of +one or more path components, and returns an indication whether that name +is safe for the process to use. + +Safe means that the pathname doesn't contain any component which could be +tampered with by a user other than the real user ID of the caller, or else +root. + +## What is significance of this check? + +Checking the permissions of an object is insufficient. Suppose we are +a superuser process such as a server trying to access some application- +specific password file `/data/path/to/passwd`. + +If we check that the permissions and ownership on this `passwd` file are all +right (root owns it, and it's not writable to anyone), that is not by itself +secure. If any of the directories in the path are open, an attacker could, +for instance, insert a symbolic link like `/data/path/to -> /malicious/to` +where `/malicious/to/passwd` is another link to `/etc/passwd`. + +## How does `safepath_check` defend against this sort of thing? + +`safepath_check` processes the path from left to right, very carefully. +Component by component it checks that every element is not writable to +anyone but the calling user (identified by `getuid`) or else root (which +is implicitly trusted). + +`safepath_check` begins by validating the `/` (root) direcgtory if the +input is an absolute path, or else the current directory `.` (dot) if +the path is relative. It then goes from there. + +If `safepath_check` encounters an insecure directory, it stops and reports it. + +## What about symlinks? + +If `safepath_check` encounters a symlink, it performs its own symlink +resolution, carefully. It reads the symlink target, grafts it in place of the +symlink, and then starts checking the substituted path in the same way. + +`safepatch_check` stops after 8 levels of symlink indirection, reporting +a loop. This is stricter than most systems' threshold for reporting `ELOOP` +in name lookup. + +`safepath_check` does not rely on the operating system symlink resolution, +which will transparently resolve multiple levels of symlink indirection. This +is not safe: symlinks can point to other symlinks. A symlink which has +tamper-proof permissions can point to a symlink which has weak permission and +can be manipulated by a different user. Every level of symlink resolution must +be performed by substitution, and a check of all the new components that are +thus inserted into the path. + +## License + +`safepath` is offered under the two-clause BSD license. See the copyright +header in the source files and the LICENSE file in the source tree. |