mirror of
https://github.com/pyenv/pyenv.git
synced 2025-11-10 20:43:48 -05:00
Re-allow paths in .python-version provided that they resolve to within the versions dir (#2442)
* Fixes #2430 while still preventing CVE-2022-35861 * Adds a skipped version message to stderr Co-authored-by: Ivan Pozdeev <vano@mail.mipt.ru>
This commit is contained in:
@@ -5,18 +5,33 @@ set -e
|
||||
|
||||
VERSION_FILE="$1"
|
||||
|
||||
function is_version_safe() {
|
||||
# As needed, check that the constructed path exists as a child path of PYENV_ROOT/versions
|
||||
version="$1"
|
||||
if [[ "$version" == ".." || "$version" == */* ]]; then
|
||||
# Sanity check the value of version to prevent malicious path-traversal
|
||||
(
|
||||
cd "$PYENV_ROOT/versions/$version" &>/dev/null || exit 1
|
||||
[[ "$PWD" == "$PYENV_ROOT/versions/"* ]]
|
||||
)
|
||||
return $?
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
if [ -s "$VERSION_FILE" ]; then
|
||||
# Read the first non-whitespace word from the specified version file.
|
||||
# Be careful not to load it whole in case there's something crazy in it.
|
||||
IFS="${IFS}"$'\r'
|
||||
IFS="$IFS"$'\r'
|
||||
sep=
|
||||
while read -n 1024 -r version _ || [[ $version ]]; do
|
||||
if [[ -z $version || $version == \#* ]]; then
|
||||
if [[ -z "$version" || "$version" == \#* ]]; then
|
||||
# Skip empty lines and comments
|
||||
continue
|
||||
elif [ "$version" = ".." ] || [[ $version == */* ]]; then
|
||||
# The version string is used to construct a path and we skip dubious values.
|
||||
# This prevents issues such as path traversal (CVE-2022-35861).
|
||||
elif ! is_version_safe "$version"; then
|
||||
# CVE-2022-35861 allowed arbitrary code execution in some contexts and is mitigated by is_version_safe.
|
||||
echo "pyenv: invalid version \`$version' ignored in \`$VERSION_FILE'" >&2
|
||||
continue
|
||||
fi
|
||||
printf "%s%s" "$sep" "$version"
|
||||
|
||||
Reference in New Issue
Block a user