我有一个bash脚本,我正在修改接受来自stdin的key = value对。 (它由xinetd产生。)我怎样才能安全地将这些key = value对转换为子进程的环境变量?设置计算环境变量的安全方法
我打算只允许以预定义前缀“CMK_”开头的键,以避免IFS或任何其他“危险”变量设置。但简单的做法
function import()
{
local IFS="="
while read key val; do
case "$key" in CMK_*)
eval "$key=$val";;
esac
done
}
是可怕的不安全因为$ val可能包含各种讨厌的东西。这似乎是它的工作:
shopt -s extglob
function import()
{
NORMAL_IFS="$IFS"
local IFS="="
while read key val; do
case "$key" in CMK_*([a-zA-Z_]))
IFS="$NORMAL_IFS"
eval $key='$val'
export $key
IFS="="
;;
esac
done
}
,但(1)它使用了我以前从未使用过的时髦extglob的事情,和(2)它的复杂,以至于我不能感到满意,认为它是安全的。
我的目标,具体而言,是允许key = value设置通过bash脚本进入被调用进程的环境。这是由子过程来处理潜在的敌对价值。
我正在修改别人的脚本,所以我不想只将它转换为Perl,并用它来完成。我也宁可不改变它周围的不同调用子进程,像
#!/bin/sh
...start of script...
perl -nle '($k,$v)=split(/=/,$_,2); $ENV{$k}=$v if $k =~ /^CMK_/; END { exec("subprocess") }'
...end of script...
更新:我结束了使用为重点检查:
if [ "$key" = "${key%[^a-zA-Z_0-9]*}" ]; then
它不要求extglob(全局设置)或regexes(仅在bash> = 3时)。它通过丢弃任何不在允许字符的白名单中的任何东西,然后将结果与原始字符进行比较。如果什么都没有被抛出,那么整个密钥必须只包含白名单的字符。
回复:为什么我要重新设置IFS。在某些情况下,我收到错误“CMK_TEST:找不到命令”,因为它在=符号上分裂。至于什么时候发生,我仍然有点困惑,因为在简单的测试中它不会。 – sfink
我不知道申报。这是一个有用的位。避免评估总是好的。但是我最终使用了避免使用extglob或正则表达式的东西(因此满足了我的秘密议程,即保留在完全由我的任意体验和舒适级别描述的bash的便携式子集中。)我将用我的更新主帖结束了使用。 – sfink