| .gitignore | ||
| COPYING | ||
| doc.go | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| main.go | ||
| Makefile | ||
| README.md | ||
http-faccess
http-faccess -- HTTP server that reports whether the server's process owner can read files relative to a base directory.
SYNOPSIS
.
http-faccess [-address addr] [-base dir] [-access log] [-error log]
[-gid gid] [-mode mode]
http-faccess -version
http-faccess -help
DESCRIPTION
http-faccess is an HTTP server that reports, through response status codes, whether the file or directory represented by the URL path is readable by the server's process owner. The URL path is interpreted as a path on the server's host relative to a given base directory. http-faccess is meant to be used as a tool within trusted networks, and should not be exposed to the public internet (see SECURITY).
base is a directory on the host on which http-faccess runs (by default, the current working directory when http-faccess was invoked). The process owner is the effective user running http-faccess. base MUST be a directory, and it MUST be readable by the process owner when http-faccess is invoked.
The URL path of a request, without the leading '/', is interpeted as a path relative to the base directory. The only permitted request methods are GET and HEAD. Response bodies are always empty; the information in the response is defined solely by its status code. Responses from http-faccess are not cacheable.
The response status codes are:
204 No Content: the file or directory represented
by the URL path is readable
301 Moved Permanently: redirect to a path without repeated
slashes (see below)
403 Forbidden: the file or directory exists, but is
not readable
404 Not Found: the file or directory does not exist
405 Method Not Allowed: the request method was neither of GET
or HEAD
500 Internal Server Error: an error was encountered while
attempting to determine readability
If the URL path ends with '/', then it denotes a directory, otherwise a file. If the URL in a request denotes a file (there is no trailing '/'), but there is a directory at the corresponding path on the host, then the response is 404 Not Found. Similarly, the response is 404 if the request denotes a directory but there is a file at the corresponding path.
Requests for the root document -- in which the path consists only of '/', or when the request URI has no trailing slash, such as http://example.com -- always result in status 204. The rationale is that these requests designate the base directory, which had to be readable when http-faccess started.
If there is a symbolic link at the path corresponding to the URL path, the link is followed to its target, possibly over a chain of links, and results are reported for the target. Dangling links result in a 500 error response.
If the URL path contains sequences of slashes, such as '//foo/bar//baz', http-faccess returns a 301 redirect response, in which the Location contains the path without the duplicate slashes.
If any component of the URL path is a single dot ('/./'), then it is transparently removed from the path. '/../' has the usual meaning of designating the parent directory, except that it goes no higher than the document root, so it is not possible to explore the filesystem outside of the base directory. Paths containing '/./' or '/../' are modified transparently before the path is evaluated for readability; there is no redirect response in such cases, unless there are also repeated slashes.
For example:
URL path: is evaluated as:
/./foo /foo
/foo/./bar /foo/bar
/.. /
/../foo /foo
/../dir/ /dir/
/dir/../foo /foo
/dir1/dir2/../foo /dir1/foo
EXAMPLES
Suppose that http-faccess is invoked as user smith with:
$ http-faccess -address :7357 -base /foo/
The server then listens at port 7357, and reports the readability of files and directories in /foo/ for user smith.
Suppose further that /foo/ has these contents, where jones is another user, and smith belongs to the group smithgrp, but not to the group jonesgrp:
$ ls -l /foo/
-rw-r--r-- smith smithgrp bar.txt
-rw-r----- jones jonesgrp baz.html
-rw-r----- jones smithgrp quux.jpg
drwxr-xr-x smith smithgrp subdir
Then http-faccess returns the following status codes for requests with these URL paths:
URL path: /
Status: 204
The root path is always readable.
URL path: /bar.txt
Status: 204
/foo/bar.txt is readable for smith.
URL path: /baz.html
Status: 403
/foo/baz.html exists, but is not readable for smith.
URL path: /quux.jpg
Status: 204
/foo/quux.jpg is readable for smith.
URL path: /subdir
Status: 404
/foo/subdir/ is a directory, but the URL path designates a file.
URL path: /subdir/
Status: 204
Directory /foo/subdir/ is readable for smith.
URL path: /../
Status: 204
Evaluated as the root path.
URL path: /subdir/../bar.txt
Status: 204
Interpreted as /bar.txt
URL path: /././quux.jpg
Status: 204
Interpreted as /quux.jpg
URL path: //bar/baz//quux
Status: 301
Location: /bar/baz/quux
Redirect to the path without repeated slashes.
OPTIONS
http-faccess may be invoked with these command-line flags:
-base dir
Evaluate URL paths in requests as paths relative to the directory dir. dir MUST be a directory, and it MUST be readable by the process owner at invocation. http-faccess always evaluates paths relative to dir as it was at invocation time, even if its name or permissions change after the server was started. By default, dir is the current working directory at invocation.
-address addr
Listen for requests at addr. addr can have one of the forms:
[ip-address]:port
unix@/path/to/unix.sock
The first form specifies an IP address. If only :port is specified, http-faccess listens at that port on all IP network interfaces. The second form specifies a Unix domain socket at the path after "unix@". The socket file is created when the server starts; if any file already exists at that path, then http-faccess fails to start. By default, http-faccess listens at port :7357.
-gid groupid
Set the numeric group id of the socket file created when the server starts, if a Unix domain socket was specified by the -address option. Ignored if the server is listening at an IP address. If groupid is -1, then the gid of the socket file is not changed -- this is the default.
-mode mode
Set the permissions of the socket file created when the server starts, if a Unix domain socket was specified by the -address option. Ignored if the server is listening at an IP address. If the value of mode has a leading 0, it is interpreted as an octal number, so that the customary notation for permissions can be used (such as 0660). If mode is -1, the permissions of the socket file are not changed -- this is the default.
-access logfile
Write the server access log (in Common Log Format) to logfile, or to standard output if logfile is "-". To suppress logging, set logfile to /dev/null. By default, http-faccess logs to stdout.
-error logfile
Write error logs, which detail the errors that cause 500 responses, to logfile, or to stdout if logfile is "-". Suppress error logs by setting logfile to /dev/null. By default, http-faccess writes error logs to stderr.
-version
Print the version and exit.
-help
Print a usage message and exit.
LIMITATIONS
http-faccess is platform-specific -- it only runs on Unix systems with a POSIX-compliant implementation of faccessat(2).
There is always a TOCTOU race between the server's reports about the readability of a file or directory and subsequent attempts by the process owner to read that file or directory. The file may be changed or deleted at any time after http-faccess reports a result.
Requests that lead to redirect responses (to paths without repeated slashes) are not logged in the access log.
SECURITY
Depending on the contents of the base directory, http-faccess can expose sensitive information about the host's file system, which could be exploited by an attacker. http-faccess does not reveal the contents of any file, does not allow directory listings, does not report the causes of 500 errors in the response (these are only reported in the server's error log), and does not permit the use of '/../' to navigate outside the base directory. But an attacker may draw inferences by testing hypotheses about paths on the host, by discovering what is readable or not readable and what exists or does not exist, or by determining that errors can be caused.
It is strongly advised:
-
don't expose http-faccess on the public internet.
-
don't run http-faccess as root, as an administrative user, as any user corresponding to a human user, or any highly privileged user.
-
don't set the base directory so that sensitive information on the host can be explored, such as the root directory ('/'), /etc, /usr or anyone's home directory.
For best results, limit the use of http-faccess to private networks, run it as a user with limited privileges, and set the base directory so that a narrowly restricted set of paths are accessible. If http-faccess only needs to be accessed by other components on the same host, consider using a Unix domain socket as the listener, so that it is not exposed on the network at all.
Be aware that http-faccess follows symbolic links, which may make it possible to explore the file system outside of the base directory. Consider eliminating symbolic links altogether from paths that can be reached from the base directory. If links are used, ensure that they are limited in scope, just as you would for the base directory.
INSTALLATION
To pull the Docker image:
docker pull uplex/http-faccess[:tag]
Building the binary requires an installation of the gogitversion tool. Re-building README.md requires goreadme. See the links in SEE ALSO below.
To install the binary:
make install
See the Makefile for additional targets, useful for development.
SEE ALSO
-
source code repository: https://code.uplex.de/testing/http-faccess
-
dockerhub registry: https://hub.docker.com/r/uplex/http-faccess
-
gogitversion: https://github.com/slimhazard/gogitversion
-
goreadme: https://github.com/dmjones/goreadme
COPYRIGHT
Copyright (c) 2020 UPLEX Nils Goroll Systemoptimierung. All rights reserved
Author: Geoffrey Simmons geoffrey.simmons@uplex.de
See LICENSE
generated with goreadme