I personally avoid giving PHP applications access to any executables except those really required. Setting open_basedir
is only effective inside PHP code itself, without any effect on external binaries. Even if the PHP application can be trusted it can potentially be compromised by an attacker. Disabling allow_url_include
ini setting, eval()
pseudo-function, etc. can make these attacks harder but with PHP you're never really safe.
The workaround I use is to have a separate bin/
directory per web application (/srv/bin/web/WEBAPP_ID in my case), only having a set of executables known to be safe. Set PATH system variable for PHP interpreter to include this directory. Hardlinks or shell wrapper scripts can potentially be used in those directories to avoid duplicating executable files (symlinks make no sense here as they are dereferenced by PHP before enforcing basedir restrictions). The shell wrappers also allows to restrict arguments passed to the actual executable. On UNIX-like systems it also makes much sense to have all directories writeable by PHP applications mounted with noexec
flag.
A working example of shell wrapper for GhostScript (you can add some logging if needed):
#!/bin/bash
GS_BASE_DIR="/path/to/temp/directory"
for T_ARG in "${@}"; do
case "${T_ARG}" in
'-d'*|'-q'|'-r'*x*|'-sDEVICE='*|"-sOutputFile=${GS_BASE_DIR}/"*|'-sOutputFile=-'|'-f-'|"-f${GS_BASE_DIR}/"*|"${GS_BASE_DIR}/"*|'-')
# OK - no op
;;
*)
exit 254;
;;
esac
done
exec /usr/bin/gs "${@}"