如何通过参数删除文件夹并通过用户保护bugs/errors
How to delete a folder by parameter and protect by user bugs/errors
假设我在脚本中有如下内容,它获取脚本输入并删除该文件夹:
cd ` dirname "[=11=]" `
X=""
rm -rf ${X}/*
我在这段代码中发现了一些错误:
- 如果用户发送
/
或无效的内容 - 将执行 rm -rf /
。
- 用户可以发送
..
、../..
,基本上他可以移动文件夹。
用户是使用此脚本的公司的开发人员,我不是在谈论黑客、客户端请求等。所以我主要是在谈论开发人员的错误和对他们正在做的事情缺乏了解这个脚本。
我想防止 rm -rf /
场景和任何不从脚本位置向下的文件夹中删除的内容。
我该如何解决?
我在想类似的事情:
cd ` dirname "[=12=]" `
X=""
rm -rf ./${X}/*
但即使这样也没有解决 ..
和 ../..
的错误。我相信有一个优雅的解决方案。
Shell 不是一种以安全为中心的语言。充其量您可以预见最明显的风险用户错误,这就是我建议您检查用户输入的路径是否在允许的基本目录内。
至少,它可以防止一些最严重的用户错误。
#!/usr/bin/env sh
user_entry=""
# Define the allowed base directory
allowed_base_dir="$PWD"
# Collect the real path of the user entered directory
real_entered_dir="$(
cd "$user_entry" 2>/dev/null && echo "$PWD"
)"
# Check the real user provided path starts with the allowed path
case $real_entered_dir in
"$allowed_base_dir"*)
echo 'ok'
echo rm -rf -- "$real_entered_dir"
;;
*)
printf 'User entered path "%s" expanding to "%s", which is not within the allowd "%s"\n' \
"$user_entry" "$real_entered_dir" "$allowed_base_dir" >&2
exit 1
;;
esac
如果您只是想避免意外错误,那么可以保持简单。假设您的系统上有 GNU readlink
:
#!/usr/bin/env bash
die() { echo "ERROR: $*" >&2; exit 1; }
source_file=$(readlink -m -- "${BASH_SOURCE:-[=10=]}")
source_dir=${source_file%/*}
dest_file=$(readlink -m -- "")
[[ -e "$dest_file" ]] || die "Received argument '$dest_file', which does not exist"
[[ $dest_file = "$source_dir"/* ]] || die "File must be under $source_dir"
rm -rf -- "$dest_file"
因为 readlink -m
试图找到真实的绝对路径,所以它会处理 ..
走上树之类的事情。
假设我在脚本中有如下内容,它获取脚本输入并删除该文件夹:
cd ` dirname "[=11=]" `
X=""
rm -rf ${X}/*
我在这段代码中发现了一些错误:
- 如果用户发送
/
或无效的内容 - 将执行rm -rf /
。 - 用户可以发送
..
、../..
,基本上他可以移动文件夹。
用户是使用此脚本的公司的开发人员,我不是在谈论黑客、客户端请求等。所以我主要是在谈论开发人员的错误和对他们正在做的事情缺乏了解这个脚本。
我想防止 rm -rf /
场景和任何不从脚本位置向下的文件夹中删除的内容。
我该如何解决?
我在想类似的事情:
cd ` dirname "[=12=]" `
X=""
rm -rf ./${X}/*
但即使这样也没有解决 ..
和 ../..
的错误。我相信有一个优雅的解决方案。
Shell 不是一种以安全为中心的语言。充其量您可以预见最明显的风险用户错误,这就是我建议您检查用户输入的路径是否在允许的基本目录内。
至少,它可以防止一些最严重的用户错误。
#!/usr/bin/env sh
user_entry=""
# Define the allowed base directory
allowed_base_dir="$PWD"
# Collect the real path of the user entered directory
real_entered_dir="$(
cd "$user_entry" 2>/dev/null && echo "$PWD"
)"
# Check the real user provided path starts with the allowed path
case $real_entered_dir in
"$allowed_base_dir"*)
echo 'ok'
echo rm -rf -- "$real_entered_dir"
;;
*)
printf 'User entered path "%s" expanding to "%s", which is not within the allowd "%s"\n' \
"$user_entry" "$real_entered_dir" "$allowed_base_dir" >&2
exit 1
;;
esac
如果您只是想避免意外错误,那么可以保持简单。假设您的系统上有 GNU readlink
:
#!/usr/bin/env bash
die() { echo "ERROR: $*" >&2; exit 1; }
source_file=$(readlink -m -- "${BASH_SOURCE:-[=10=]}")
source_dir=${source_file%/*}
dest_file=$(readlink -m -- "")
[[ -e "$dest_file" ]] || die "Received argument '$dest_file', which does not exist"
[[ $dest_file = "$source_dir"/* ]] || die "File must be under $source_dir"
rm -rf -- "$dest_file"
因为 readlink -m
试图找到真实的绝对路径,所以它会处理 ..
走上树之类的事情。