...
- Use full paths for the programs you are executing. For example,
- shell: /bin/ls -l file
- python: subprocess.Popen(["/bin/ls", "-l", "file"])
- If your external programs can be found in a variety of locations depending on the system on which they are run, use exact control over the PATH used to find your programs. For example, you can add a line to the beginning of your program such as:
- shell: export PATH=/bin:/usr/bin or export PATH=/sbin:/usr/sbin:/bin:/usr/bin
- python: os.environ['PATH'] = '/bin:/usr/bin' or os.environ['PATH'] = '/sbin:/usr/sbin:/bin:/usr/bin'
- If you must depend on an externally-provided path, combine prepending known locations to the beginning of the PATH, and sanitize with sanitizing the rest of it. For example, you can add a line to the beginning of your program such as:
- bash shell: export PATH="/bin:/usr/bin:$(sanitize "$PATH")"
- python: os.environ['PATH'] = f"/bin:/usr/bin:{sanitize(os.environ['PATH'])}"
- The purpose of You will have to write the sanitize() invocation function. Some things to consider are:
- The current directory is dangerous in the PATH, except possibly at the end. So one thing your sanitize function should do is to remove
- the current directory, or any aliases that map into the current directory (e.g.
::
,:.:
,:./:
,:./.:
, etc.). - It's also dangerous for any of the directories found in the PATH to be world writable, where someone can create a program with the same name as a system tool invoked by your program. (Consider having a PATH with
/tmp
in it, where someone could have placed a script named "ls
".)
- Use exact control over the command line arguments. For example, in Python avoid using "shell=True" with the subprocess module's methods, which can allow unexpected parsing or expansion of the values being passed.
...