mirror of
https://github.com/robbyrussell/oh-my-zsh.git
synced 2026-09-28 14:06:12 +02:00
fix(installer): prevent command injection via $USER in install.sh (#13960)
HOME="${HOME:-$(eval echo ~"$USER")}" expands any shell metacharacters in
$USER when HOME is unset (CWE-78), e.g. USER='x"; <command>; "'. Validate the
username against a safe character set before running the eval and fall back
to $PWD for unsafe values. Also quote $USER in the getent call to avoid word
splitting.
Co-authored-by: Carlo Sala <carlosalag@protonmail.com>
This commit is contained in:
+25
-3
@@ -49,9 +49,31 @@ USER=${USER:-$(id -u -n)}
|
|||||||
# $HOME is defined at the time of login, but it could be unset. If it is unset,
|
# $HOME is defined at the time of login, but it could be unset. If it is unset,
|
||||||
# a tilde by itself (~) will not be expanded to the current user's home directory.
|
# a tilde by itself (~) will not be expanded to the current user's home directory.
|
||||||
# POSIX: https://pubs.opengroup.org/onlinepubs/009696899/basedefs/xbd_chap08.html#tag_08_03
|
# POSIX: https://pubs.opengroup.org/onlinepubs/009696899/basedefs/xbd_chap08.html#tag_08_03
|
||||||
HOME="${HOME:-$(getent passwd $USER 2>/dev/null | cut -d: -f6)}"
|
if [ -z "$HOME" ]; then
|
||||||
# macOS does not have getent, but this works even if $HOME is unset
|
HOME=$(getent passwd "$USER" 2>/dev/null | cut -d: -f6)
|
||||||
HOME="${HOME:-$(eval echo ~"$USER")}"
|
|
||||||
|
# macOS does not have getent; fall back to tilde expansion, but only if
|
||||||
|
# $USER is a safe username. The eval below would otherwise expand any shell
|
||||||
|
# metacharacters in $USER and allow command injection (CWE-78).
|
||||||
|
case "$USER" in
|
||||||
|
*[![:alnum:]_.-]*|'')
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
resolved_home=$(eval echo ~"$USER")
|
||||||
|
# Unknown users are not expanded and produce a literal "~username".
|
||||||
|
[ "$resolved_home" = "~$USER" ] || HOME=$resolved_home
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$HOME" in
|
||||||
|
/*) ;;
|
||||||
|
*)
|
||||||
|
echo "Error: unable to determine the current user's home directory." >&2
|
||||||
|
echo "Set HOME explicitly and rerun the installer." >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Track if $ZSH was provided
|
# Track if $ZSH was provided
|
||||||
|
|||||||
Reference in New Issue
Block a user