设置计算环境变量的安全方法 [英] Safe way to set computed environment variables

查看:150
本文介绍了设置计算环境变量的安全方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个bash脚本,我正在修改以接受来自stdin的key = value对。 (它由xinetd产生)我如何安全地将这些key = value对转换为子进程的环境变量?



我计划只允许以预定义开始的键前缀CMK_,以避免IFS或任何其他危险变量设置。但是简单的方法

  function import()
{
local IFS ==
读取键值;
$$ key = $ val;
esac
done
}

是非常不安全的,因为$ val可能包含各种讨厌的东西。这似乎是有效的:

  shopt -s extglob 
function import()
{
NORMAL_IFS =$ IFS
local IFS ==
while read key val;在CMK _ *([a-zA-Z_])中执行
case$ key)
IFS =$ NORMAL_IFS
eval $ key ='$ val'
export $ key
IFS ==
;;
esac
done
}

但(1)它使用我以前从未使用过的时髦的extglob的东西,和(2)它是非常复杂的,我不能舒服,它的安全。



我的目标,具体来说,是允许key = value设置将bash脚本传递到被调用进程的环境中。我们正在修改别人的脚本,所以我不想把它转换成Perl和完成它。我也不会改变它,以不同的方式调用子进程,像

 #!/ bin / sh 
...开始脚本...
perl -nle'($ k,$ v)= split(/ = /,$ _,2); $ ENV {$ k} = $ v如果$ k =〜/ ^ CMK_ /; END {exec(subprocess)}'
...脚本结束...

更新:我最终用于密钥检查的是:

  if [$键=$ {key%[^ a-zA-Z_0-9] *}];然后

它不需要extglob(全局设置)或正则表达式(仅在bash> = 3) 。它通过抛出不允许的字符白名单中的任何内容,然后将结果与原始文本进行比较。如果没有任何东西被抛出,那么整个密钥必须只包含白名单的字符。

解决方案

这很多更安全使用声明 eval

  shopt -s extglob 
function import()
{
NORMAL_IFS =$ IFS
local IFS ==
while key key;
$$ key
CMK _ *([a-zA-Z_]))
IFS =$ NORMAL_IFS
declare $ key =$ val2& ; / dev / null || echoBad key
IFS ==#为什么要设置这里?
;;
*)
echoBad key
;;
esac
done
}

如果你不想要使用 extglob ,可以使用正则表达式匹配测试:

  while ... 
如果[[$ key =〜CMK_]]#或类似的东西:[[$ key =〜CMK _ [[:alpha:]]]]
then
declare ..
else
echo坏账
fi

另外,请参阅


I have a bash script that I am modifying to accept key=value pairs from stdin. (It is spawned by xinetd.) How can I safely convert those key=value pairs into environment variables for subprocesses?

I plan to only allow keys that begin with a predefined prefix "CMK_", to avoid IFS or any other "dangerous" variable getting set. But the simplistic approach

function import ()
{
    local IFS="="
    while read key val; do
        case "$key" in CMK_*)
            eval "$key=$val";;
        esac
    done
 }

is horribly insecure because $val could contain all sorts of nasty stuff. This seems like it would work:

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
 }

but (1) it uses the funky extglob thing that I've never used before, and (2) it's complicated enough that I can't be comfortable that it's secure.

My goal, to be specific, is to allow key=value settings to pass through the bash script into the environment of called processes. It is up to the subprocesses to deal with potentially hostile values getting set.

I am modifying someone else's script, so I don't want to just convert it to Perl and be done with it. I would also rather not change it around to invoke the subprocesses differently, something like

#!/bin/sh
...start of script...
perl -nle '($k,$v)=split(/=/,$_,2); $ENV{$k}=$v if $k =~ /^CMK_/; END { exec("subprocess") }'
...end of script...

Update: What I ended up using for the key check is:

if [ "$key" = "${key%[^a-zA-Z_0-9]*}" ]; then

It doesn't require extglob (global setting) or regexes (only in bash >= 3). It works by throwing out anything not in a whitelist of allowed characters, then comparing the result to the original. If nothing was thrown out, then the whole key must contain only whitelisted characters.

解决方案

It's much safer to use declare than eval:

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"
                declare $key="$val"  2>/dev/null || echo "Bad key"
                IFS="="   # why set this here?
                ;;
            *)
                echo "Bad key"
                ;;
        esac
    done
}

If you don't want to use extglob, you can use a regex matching test:

while ...
if [[ $key =~ CMK_ ]]    # or something like: [[ $key =~ CMK_[[:alpha:]] ]]
then
    declare ...
else
    echo "Bad key"
fi

Also, see this.

这篇关于设置计算环境变量的安全方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆