这是eval cat inside a function的后续问题。
我正在使用eval
来模仿其他语言(例如JavaScript)的import
功能。自从我建立了压倒性的脚本文件集合以来,这就是我想在本地计算机上做一段时间的事情。
原因是,我现在在单独的文件中具有大量单独的功能,并且我不想每次想调用该功能时都一次又一次地用source
不断读取文件。 / p>
主要是为了娱乐,但是我不想在不那么随意的情况下使用它:
import_as() {
import_name="$1"
import_fnname="${2:-"$import_name"}"
if test -f "$1"; then
echo "File '$1' doesn't exist."
fi
case "$2" in
*[!-a-zA-Z0-9_]* ) echo "BAD";;
*) eval "$2"'() { '"$(< $1.sh)"'; }' ;;
esac
}
下面是使用中的示例:
add.sh
#!/bin/sh
echo "$(($1 + $2))"
sub.sh
#!/bin/sh
echo "$(($1 - $2))"
example_import.sh
import_as "add" "math_add"
import_as "sub"
math_add 2 5 # Returns "7"
math_subtract 5 1 # Returns "4"
我的问题是,eval
的这种用例在执行检查后是否容易受到攻击,或者此脚本中是否存在可利用的东西?
PS:我知道eval
被认为是邪恶的,我不想听到这作为答案。如果您认为在eval
的这个用例中可能存在漏洞,那么我想对此用例进行具体推理。
答案 0 :(得分:0)
如果您信任import_as
和$1
的论点-$2
和$1
,以及eval
所引用文件的内容- -以上是安全的。 {{1}}是邪恶的,因为它允许将数据评估为代码;如果您要对这些内容进行硬编码,则它们是(可信)代码的一部分,而不是(不可信)数据的一部分。
答案 1 :(得分:0)
在回顾了查尔斯·达菲的精彩回答和评论后,此代码已被评估为更安全:
import_as() {
# Charles Duffy's suggestions, including side effect reduction.
current_lc_ctype="$LC_CTYPE"
LC_CTYPE=C
import_name="$1"
import_fnname="${2:-"$import_name"}"
case "$import_name" in
*[!/]*) echo "BAD - local directory only."; return ;;
*) echo "Okay" ;;
esac
if test -f "$import_name"; then
echo "File '$import_name' doesn't exist."
fi
case "$2" in
*[!-a-zA-Z0-9_]*) echo "BAD"; return;;
*) eval "$2"'() { '"$(< $1.sh)"'; }' ;;
esac
# Change LC_CTYPE back to prior to function call
LC_CTYPE="$current_lc_ctype"
}