我正在一个项目中使用大量的shellcript用于各种目的,性能和可移植性非常重要。其中一些脚本使用的配置文件具有以下格式:
VARIABLE1="value"
VARIABLE2="several words, several values"
VARIABLE3="a,list,of,words"
然后,要使用这些变量,我们只需要提供以下内容:
#!/bin/sh
. /path/to/the/configuration.file
echo "Var 1 is: $VARIABLE1"
echo "Var 2 is: $VARIABLE2"
echo "Var 3 is: $VARIABLE3"
简单,对吧?
不是那么多。事实是,虽然我们可以使用简单的chown root file.sh; chmod 0711 file.sh
保护脚本不被修改,但配置文件必须是可写的,然后我们发现这样的讨厌的事情可能发生:
VARIABLE1="value"; rm requiredfile.data
VARIABLE2="you dont want to see this: `rm anotherimportantfile.data`
rm thelastrequiredfile.bin
因此,当调用配置文件时,插入其中的指令将以实际调用它的任何用户的权限执行。
我知道我的要求是棘手的,但我希望能够过滤所有可能导致未经授权的代码执行的危险语法。
到目前为止我做了什么:
FILTER='
/^$/d # Delete empty lines
/^#/d # Delete comments
/^[A-Z0-9_]\+=.\+$/{ # Select assignments
/`/p # alert with `
/\$/p # alert with $
/\\/p # alert with \
/;/p # alert with ;
d # Accept the rest
}
'
C=`sed -e "$FILTER" $1 | wc -l` 2>/dev/null
if test $C -gt 0; then
echo "#ERR Suspicious strings in configuration file"
fi
我错过了什么?有什么改进吗?
PS:我知道可以使用grep
/ cut
组合安全地读取每个变量,但这对于性能问题是不可能的。
答案 0 :(得分:5)
一个经常被引用的安全范例是你应该枚举允许的模式,而不是试图枚举所有可能的不允许的模式。
如果您将自己局限于分配了始终为单引号字符串的值的变量,则必须允许的唯一模式是
^[A-Za-z_][A-Za-z0-9_]*='[^']*'[\t ]*$
尾部空格不是绝对必要的(如果你想要很好,你也可以允许引导空格。)
单引号禁止所有shell元字符;单引号中的任何字符串都是逐字记录的。
允许双引号或不带引号的字符串只会引起麻烦。过渡到单引号可能有点麻烦,但如果你来这里寻求安全建议,那就是你会得到的。
顺便提一下,您只需使用grep
查找违规行为即可:
if grep -v "^[A-Za-z_][A-Za-z0-9_]*='[^']*'[\t ]*$" configfile /dev/null >&2; then
echo "$0: Invalid lines in configfile -- aborting" >&2
exit 2
fi
. configfile
:
:
作为用户,我希望诊断消息包含违规行为。这也可以通过wc -l
避免繁琐的迂回。
答案 1 :(得分:2)
忘记过滤器。我对此问题的理解是,您不应该直接将配置文件的写/读权限授予某人。您应该只为一个组分配sudo权限,将相关用户添加到该组中。