aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md61
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.