I have an application/daemon running on a machine as one user (UserA) exposing an interface that allows other users to run certain actions (eg start_process, end_process). This runs a defined process as UserA.
I would like to add some extensibility to, for instance, run a script before starting the process. This script should be owned and accessible only by UserA as it will be run with that user's privileges. The approach I am thinking of is similar to that used by git-hooks. A configured directory is checked for executable files matching specific names that are run at relevant points.
Other users have access (as their own user) to the machine where the daemon is running.
What is the best approach to preventing an arbitrary script from being run?
The simplest approach would be to document that the directory containing the scripts should be read/writeable only by UserA and assume it is safe to run anything it contains but is there a safe way to programmatically check at runtime that it's true without exposing a toctou race condition?
The naive approach would be something like (pseudocode):
hook_directory = '/path/to/hooks' # from configuration
def run_pre_start():
hook = ${hook_directory}/pre-start
if hook.exists() and hook.has_correct_permissions():
system.exec(hook)
but this is clearly open to files being changed while it's running.
Even checking the directory when the daemon initially reads its configuration would be exploitable if any directory above in the file tree was accessible by other users, right?
Would walking the tree from / to the directory checking all segments be a valid approach?
If it's relevant, the daemon is written in rust and it will be running on a linux machine (specifically RHEL7). The 'scripts' can be any executable but will most likely be bash or python.