面试题答案
一键面试输入验证
- 参数验证:
- 在脚本开头,对传入脚本的参数进行验证。例如,如果脚本期望接收一个数字作为参数,可以使用如下方式验证:
if [ $# -ne 1 ] ||! [[ $1 =~ ^[0-9]+$ ]]; then echo "Usage: $0 <number>" exit 1 fi
- 这里
$#
检查参数个数,[[ $1 =~ ^[0-9]+$ ]]
检查第一个参数是否为纯数字。
- 用户输入验证:
- 如果脚本通过
read
命令获取用户输入,同样要进行验证。例如:
read -p "Enter a valid email address: " email if! [[ $email =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then echo "Invalid email address" exit 1 fi
- 此代码验证用户输入是否为有效的电子邮件格式。
- 如果脚本通过
命令注入防范
- 使用单引号或双引号:
- 当构建命令字符串时,尽量使用单引号(
'
)来包围参数,避免使用双引号("
),除非确实需要变量替换。例如:
user_input='some input' command='ls -l "'$user_input'"' eval $command
- 如果使用双引号,恶意用户可能通过输入
; rm -rf /
之类的内容来执行恶意命令。而单引号会将输入作为纯文本处理。
- 当构建命令字符串时,尽量使用单引号(
- 避免使用eval:
eval
是命令注入的高风险点。尽量使用其他方式来构建和执行命令。例如,如果你想动态执行命令,可以考虑使用函数:
execute_command() { local command="$1" "$@" } command_args=('ls' '-l') execute_command "${command_args[@]}"
- 这样,命令和参数被分别处理,减少了注入风险。
环境变量安全
- 限制环境变量暴露:
- 在脚本中,尽量减少不必要的环境变量暴露。如果需要设置自定义环境变量,使用局部变量代替全局环境变量。例如:
my_script() { local MY_VARIABLE='value' # 脚本内使用MY_VARIABLE }
- 这样,
MY_VARIABLE
只在函数my_script
内有效,不会污染全局环境。
- 验证环境变量来源:
- 如果脚本依赖外部设置的环境变量,要对其进行验证。例如:
if [ -z "${API_KEY:-}" ] ||! [[ ${API_KEY} =~ ^[a-zA-Z0-9]{32}$ ]]; then echo "Invalid API_KEY environment variable" exit 1 fi
- 这里检查
API_KEY
环境变量是否为空且是否为32位的字母数字组合。
网络交互安全
-
HTTPS 连接:
- 如果脚本使用
curl
或wget
进行网络请求,确保使用 HTTPS。例如:
curl -sSL https://example.com/api/data
-s
使curl
静默,-S
确保在静默模式下出错时显示错误信息,-L
使curl
跟随重定向。
- 如果脚本使用
-
证书验证:
- 对于
curl
,默认会验证服务器证书。如果要自定义证书验证,可以使用--cacert
选项指定CA证书文件。例如:
curl -sSL --cacert /path/to/ca.crt https://example.com/api/data
- 对于
wget
,可以使用--ca-certificate
选项:
wget --ca - certificate=/path/to/ca.crt https://example.com/api/data
- 对于
-
输入过滤:
- 如果脚本将用户输入或其他数据作为网络请求的一部分,要对其进行过滤。例如,如果构建一个GET请求:
user_input='safe input' url="https://example.com/api?param=$(echo $user_input | sed 's/[;&|`$]/_/g')" curl -sSL "$url"
- 这里使用
sed
命令将可能导致命令注入或其他安全问题的字符替换为下划线。
-
限制网络访问:
- 在服务器上,可以使用防火墙(如
iptables
)来限制脚本发起的网络连接。例如,只允许脚本连接到特定的服务器:
iptables -A OUTPUT -p tcp -d example.com --dport 443 -j ACCEPT iptables -A OUTPUT -p tcp --dport 443 -j DROP
- 第一条规则允许连接到
example.com
的443端口,第二条规则阻止其他所有到443端口的连接。
- 在服务器上,可以使用防火墙(如
定期审计
- 代码审查:
- 定期对Bash脚本进行人工代码审查,检查是否存在潜在的安全漏洞,特别是在输入验证、命令执行和网络交互部分。
- 自动化扫描:
- 使用工具如 ShellCheck 对脚本进行自动化扫描。它可以检测出许多常见的语法和安全问题,例如未引用的变量、可能的命令注入等。可以通过以下方式安装和使用:
# 在Ubuntu上安装 sudo apt - get install shellcheck shellcheck your_script.sh