Допустим, у меня есть скрипт bash, который действует как файл конфигурации для другого скрипта bash:
config.sh:
verbose=yes
echo "Malicious code!"
name=test
скрипт.sh:
source config.sh
echo "After sourcing: verbose='$verbose', name='$name'"
Проблема в том, что это не очень безопасно, поскольку все, что указано в config.sh, будет запущено:
$ ./script.sh
Malicious code!
After sourcing: verbose='yes', name='test'
Чтобы сделать это более безопасным, я подумал, что выделю операции присваивания и выполню только их. Я бы сделал это, передав source
"документ here":
скрипт.sh:
source <<EOF
$(grep -P '^\s*\w+=' test.sh)
EOF
echo "After sourcing: verbose='$verbose', name='$name'"
(Да, я знаю, что регулярное выражение не такое уж и сильное; это просто заполнитель.) К сожалению, источник, похоже, не очень хорошо работает с этими документами:
./script.sh: line 1: source: filename argument required
source: usage: source filename [arguments]
After sourcing: verbose='', name=''
Очевидно, я мог бы сделать множество вещей, чтобы получить данные конфигурации из файла, и это, в любом случае, вероятно, более безопасно.
Но зуд все еще не прошел; хочу выяснить, сработает ли то, что я пробовал. Есть предложения?
решение1
source <(cat << EOF
A=42
EOF
)
echo $A
Выход:
42
решение2
source
необходимо имя файла, вы не можете перенаправить ввод на него.
В моей системе вместо этого я смог использовать замену процесса:
source <( grep = test.sh )
Замените =
соответствующим регулярным выражением.
решение3
Вы можете напрямую eval
это сделать:
eval "$(grep -P '^\s*\w+=' config.sh)"
#quotes needed if you want the full content of the file (including newlines etc.)
По сути, подбор поставщиков такой же, как:
eval "$(cat file)"
Однако следует отметить, что люди могут выполнять все коды справа от знака равенства:
a=$(evil_code_here)
b=`evil_code_here`
c="something" evil_code_here
#etc.
Вам нужен фильтр получше.