## 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.