diff --git a/contrib/scripts/ast_coredumper b/contrib/scripts/ast_coredumper index e081067545..920974a380 100755 --- a/contrib/scripts/ast_coredumper +++ b/contrib/scripts/ast_coredumper @@ -42,11 +42,9 @@ COMMANDLINE_COREDUMPS=false # Read config files from most important to least important. # Variables set on the command line or environment always take precedence. -# shellcheck disable=SC1091 -[ -f ./ast_debug_tools.conf ] && source ./ast_debug_tools.conf -# shellcheck disable=SC1090 -[ -f ~/ast_debug_tools.conf ] && source ~/ast_debug_tools.conf -[ -f /etc/asterisk/ast_debug_tools.conf ] && source /etc/asterisk/ast_debug_tools.conf +safe_source_config ./ast_debug_tools.conf +safe_source_config ~/ast_debug_tools.conf +safe_source_config /etc/asterisk/ast_debug_tools.conf if [ -n "${DATEFORMAT}" ] ; then err <<-EOF @@ -435,6 +433,43 @@ check_gdb() { fi } +# Function to safely source a config file with security checks +# This prevents privilege escalation by ensuring config files are +# owned by root and not writable by group or others +safe_source_config() { + local config_file="$1" + + # Return if file doesn't exist + [ -f "$config_file" ] || return 0 + + # Get the absolute path + config_file=$(readlink -f "$config_file") + + # Get file owner UID and permissions + local file_stat + file_stat=$(stat -c "%u %a" "$config_file" 2>/dev/null) || return 0 + local owner_uid=${file_stat%% *} + local perms=${file_stat##* } + + # File must be owned by root (UID 0) + if [ "$owner_uid" -ne 0 ]; then + err "Config file $config_file is not owned by root. Skipping for security." >&2 + return 1 + fi + + # File must not be writable by group or others (check group-write and other-write bits) + # Extract the group and other permission digits + local group_perms=$((perms / 10 % 10)) + local other_perms=$((perms % 10)) + + if [ $((group_perms & 2)) -ne 0 ] || [ $((other_perms & 2)) -ne 0 ]; then + err "Config file $config_file is writable by group or others. Skipping for security." >&2 + return 1 + fi + + source "$config_file" +} + # shellcheck disable=SC2317 find_pid() { if [ -n "$PID" ] ; then diff --git a/contrib/scripts/ast_logescalator b/contrib/scripts/ast_logescalator index 054ef9b9c0..ea3d15e429 100755 --- a/contrib/scripts/ast_logescalator +++ b/contrib/scripts/ast_logescalator @@ -128,10 +128,51 @@ declare -A DEBUG_COMMANDS=( VERBOSE_LEVELS="NOTICE,WARNING,ERROR,VERBOSE" DEBUG_LEVELS="DEBUG" +# Function to safely source a config file with security checks +# This prevents privilege escalation by ensuring config files are +# owned by root and not writable by group or others when running as root +safe_source_config() { + local config_file="$1" + + # Return if file doesn't exist + [ -f "$config_file" ] || return 0 + + # Get the absolute path + config_file=$(readlink -f "$config_file") + + # Check if running as root (effective UID is 0) + if [ $EUID -eq 0 ]; then + # Running as root - apply strict security checks + # Get file owner UID and permissions + local file_stat + file_stat=$(stat -c "%u %a" "$config_file" 2>/dev/null) || return 0 + local owner_uid=${file_stat%% *} + local perms=${file_stat##* } + + # File must be owned by root (UID 0) + if [ "$owner_uid" -ne 0 ]; then + echo "WARNING: Config file $config_file is not owned by root. Skipping for security." >&2 + return 1 + fi + + # File must not be writable by group or others (check group-write and other-write bits) + # Extract the group and other permission digits + local group_perms=$((perms / 10 % 10)) + local other_perms=$((perms % 10)) + + if [ $((group_perms & 2)) -ne 0 ] || [ $((other_perms & 2)) -ne 0 ]; then + echo "WARNING: Config file $config_file is writable by group or others. Skipping for security." >&2 + return 1 + fi + fi + + source "$config_file" +} + # Read config files from least important to most important -[ -f /etc/asterisk/ast_debug_tools.conf ] && source /etc/asterisk/ast_debug_tools.conf -[ -f ~/ast_debug_tools.conf ] && source ~/ast_debug_tools.conf -[ -f ./ast_debug_tools.conf ] && source ./ast_debug_tools.conf +safe_source_config /etc/asterisk/ast_debug_tools.conf +safe_source_config ~/ast_debug_tools.conf +safe_source_config ./ast_debug_tools.conf DATEFORMAT=${DATEFORMAT:-'date +%FT%H-%M-%S%z'} UNIQUEID=$($DATEFORMAT) diff --git a/contrib/scripts/ast_loggrabber b/contrib/scripts/ast_loggrabber index b549ec329a..0683dfd991 100755 --- a/contrib/scripts/ast_loggrabber +++ b/contrib/scripts/ast_loggrabber @@ -101,10 +101,51 @@ append_logfiles=false declare -a LOGFILES declare -a ARGS_LOGFILES +# Function to safely source a config file with security checks +# This prevents privilege escalation by ensuring config files are +# owned by root and not writable by group or others when running as root +safe_source_config() { + local config_file="$1" + + # Return if file doesn't exist + [ -f "$config_file" ] || return 0 + + # Get the absolute path + config_file=$(readlink -f "$config_file") + + # Check if running as root (effective UID is 0) + if [ $EUID -eq 0 ]; then + # Running as root - apply strict security checks + # Get file owner UID and permissions + local file_stat + file_stat=$(stat -c "%u %a" "$config_file" 2>/dev/null) || return 0 + local owner_uid=${file_stat%% *} + local perms=${file_stat##* } + + # File must be owned by root (UID 0) + if [ "$owner_uid" -ne 0 ]; then + echo "WARNING: Config file $config_file is not owned by root. Skipping for security." >&2 + return 1 + fi + + # File must not be writable by group or others (check group-write and other-write bits) + # Extract the group and other permission digits + local group_perms=$((perms / 10 % 10)) + local other_perms=$((perms % 10)) + + if [ $((group_perms & 2)) -ne 0 ] || [ $((other_perms & 2)) -ne 0 ]; then + echo "WARNING: Config file $config_file is writable by group or others. Skipping for security." >&2 + return 1 + fi + fi + + source "$config_file" +} + # Read config files from least important to most important -[ -f /etc/asterisk/ast_debug_tools.conf ] && source /etc/asterisk/ast_debug_tools.conf -[ -f ~/ast_debug_tools.conf ] && source ~/ast_debug_tools.conf -[ -f ./ast_debug_tools.conf ] && source ./ast_debug_tools.conf +safe_source_config /etc/asterisk/ast_debug_tools.conf +safe_source_config ~/ast_debug_tools.conf +safe_source_config ./ast_debug_tools.conf if [ ${#LOGFILES[@]} -eq 0 ] ; then LOGFILES+=(/var/log/asterisk/messages* /var/log/asterisk/queue* \ @@ -178,15 +219,14 @@ df=${tarball_uniqueid:-$(${DATEFORMAT})} # Extract the Python timestamp conver script from the end of this # script and save it to /tmp/.ast_tsconvert.py -ss=`egrep -n "^#@@@SCRIPTSTART@@@" $0 |cut -f1 -d:` -tail -n +${ss} $0 >/tmp/.ast_tsconvert.py +install -m 0600 /dev/stdin /tmp/.ast_tsconvert.py < <(sed '1,/^#@@@SCRIPTSTART@@@/ d' "$0") tmpdir=$(mktemp -d) if [ -z "$tmpdir" ] ; then echo "${prog}: Unable to create temporary directory." exit 1 fi -trap "rm -rf $tmpdir" EXIT +trap "rm -rf $tmpdir /tmp/.ast_tsconvert.py" EXIT tardir=asterisk-${df}.logfiles # Now iterate over the logfiles