Bash/Shell 脚本中的安全输入验证
Secure Input Validation in Bash/Shell Script
我正在编写一个 bash 脚本,它需要多个用户输入,主要是目录路径和文件名。该程序将创建指定的目录和文件。
在写目录路径的时候,我要求的是绝对路径——~/DIR/...,或者$PATH/DIR/.. . 或 ./DIR/... 是不允许的。目录路径应仅以 /DIR/DIR/... 的形式提供,文件路径应以 /DIR/DIR/.../ 的形式提供文件名,文件名格式为文件名。
我还想确保用户没有添加任何命令行选项(例如,如果我 运行 sudo,我想确保用户没有附加 -u 他们声明中的任何地方)到他们的输入。
但是,我不能完全确定清理他们输入的最佳方法,因为目录路径和文件名可能包含破折号、下划线、空格、句点和字母数字字符。应检测任何其他字符。
通过 read 收集用户输入。我使用的是 Ubuntu 系统,所以只要它符合 Ubuntu shell 就可以工作。
假设只安装了默认的系统包。
可以接受多个选项来处理验证的各个部分(例如,使用 --
将以下数据视为参数而不是命令 [Siguza 建议],然后使用另一个选项来处理目录路径)。
正确映射目录结构需要绝对路径。由于我在路径字符串上执行的功能,任何其他格式的路径都会导致程序在匹配或附加到其他路径时错误地解释结构。
谢谢。
有效方法:我使用了公认的答案,在某些情况下使用 realpath 和 readlink,并使用 - - 将后面的文字解释为参数。如果您想允许相对路径,请使用 readlink 或 realpath 的结果作为您的路径。如果要禁止相对路径,则将原始字符串与 readlink 或 realpath 的结果进行比较。
你可以这样做:
#!/bin/bash
set -e
while read path; do
result=`realpath -m -- "$path"`
if [ "$result" != "$path" ] && [ "$result/" != "$path" ] ; then
echo "Rejected: $path"
else
last_char_index=$((${#path}-1))
last_char=${path:$last_char_index:1}
if [ "$last_char" == "/" ]; then
echo "New directory: $path"
mkdir -- "$path"
else
echo "New file: $path"
touch -- "$path"
fi
fi
done
exit 0
我使用 realpath
来捕获相对路径,然后 总是 在双引号之间使用用户输入以避免命令注入(如果可能的话)。
我想还有更好的方法,但目前我只能想到这些。
编辑:根据评论中的建议,我添加了 --
以确保将 file/directory 名称安全地分配给 touch
、mkdir
和 realpath
.
我正在编写一个 bash 脚本,它需要多个用户输入,主要是目录路径和文件名。该程序将创建指定的目录和文件。
在写目录路径的时候,我要求的是绝对路径——~/DIR/...,或者$PATH/DIR/.. . 或 ./DIR/... 是不允许的。目录路径应仅以 /DIR/DIR/... 的形式提供,文件路径应以 /DIR/DIR/.../ 的形式提供文件名,文件名格式为文件名。 我还想确保用户没有添加任何命令行选项(例如,如果我 运行 sudo,我想确保用户没有附加 -u 他们声明中的任何地方)到他们的输入。
但是,我不能完全确定清理他们输入的最佳方法,因为目录路径和文件名可能包含破折号、下划线、空格、句点和字母数字字符。应检测任何其他字符。
通过 read 收集用户输入。我使用的是 Ubuntu 系统,所以只要它符合 Ubuntu shell 就可以工作。 假设只安装了默认的系统包。
可以接受多个选项来处理验证的各个部分(例如,使用 --
将以下数据视为参数而不是命令 [Siguza 建议],然后使用另一个选项来处理目录路径)。
正确映射目录结构需要绝对路径。由于我在路径字符串上执行的功能,任何其他格式的路径都会导致程序在匹配或附加到其他路径时错误地解释结构。
谢谢。
有效方法:我使用了公认的答案,在某些情况下使用 realpath 和 readlink,并使用 - - 将后面的文字解释为参数。如果您想允许相对路径,请使用 readlink 或 realpath 的结果作为您的路径。如果要禁止相对路径,则将原始字符串与 readlink 或 realpath 的结果进行比较。
你可以这样做:
#!/bin/bash
set -e
while read path; do
result=`realpath -m -- "$path"`
if [ "$result" != "$path" ] && [ "$result/" != "$path" ] ; then
echo "Rejected: $path"
else
last_char_index=$((${#path}-1))
last_char=${path:$last_char_index:1}
if [ "$last_char" == "/" ]; then
echo "New directory: $path"
mkdir -- "$path"
else
echo "New file: $path"
touch -- "$path"
fi
fi
done
exit 0
我使用 realpath
来捕获相对路径,然后 总是 在双引号之间使用用户输入以避免命令注入(如果可能的话)。
我想还有更好的方法,但目前我只能想到这些。
编辑:根据评论中的建议,我添加了 --
以确保将 file/directory 名称安全地分配给 touch
、mkdir
和 realpath
.