[英]How can I safely return a bash array over ssh?
在bash
shell中,可以很容易地用declare -p
引用数组,然后稍后进行eval
以使它们恢复正常。 对于通过SSH将数组(作为脚本的一部分)传递到远程计算机,这似乎可以接受。
问题是,我不希望对方获得相同级别的信任。 如果远程计算机受到威胁,则感染可能会通过未经确认的eval
语句传播到本地计算机。
当前,要在机器之间传递数组,我使用的是这样的方法:
#!/bin/bash
# Define the modules we expect to find installed on the remote machine
expected_modules=(foo-module bar 'baz 2.0')
# SSH into the remote machine, send the arrays back and forth with "declare -p"
unparsed_missing_modules=$(ssh remote-machine /bin/bash << EOF
check_for_module() {
# Placeholder so that this can be tested locally
case \$1 in
foo*) true;;
*) false;;
esac
}
$(declare -p expected_modules)
missing_modules=()
for module in "\${expected_modules[@]}"; do
if ! check_for_module "\$module"; then
missing_modules+=( "\$module" )
fi
done
declare -p missing_modules
EOF
)
# Unpack the result (this is what I want to find an alternative to)
eval "$unparsed_missing_modules"
# Do something with the result after unpacking into an array
for module in "${missing_modules[@]}"; do
echo "Warning: Remote machine is missing $module" >&2
done
当ssh
会话的输出直接传递到eval
时,此脚本中的主要不安全因素已接近尾声。 如何在bash
清理此输入?
通用,安全的答案是对数组的条目进行NUL分隔,在stdout上传递文字NUL分隔的数据,并使用while read
循环对其进行解释。
注意:
get_remote_array() {
local args
local hostname=$1; shift
printf -v args '%q ' "$@"
ssh "$hostname" "bash -s $args" <<'EOF'
# in real-world use, print something more useful than the arguments we were started with
# ...but for here, this demonstrates the point:
printf '%s\0' "$@"
EOF
}
array=( )
while IFS= read -r -d ''; do
array+=( "$REPLY" )
done < <(get_remote_array "localhost" \
$'I\ncontain\nnewlines' \
'I want to $(touch /tmp/security-fail)' \
"'"'I REALLY want to $(touch /tmp/security-fail), even in single quotes'"'")
echo "---- Shell-escaped content"
printf '%q\n' "${array[@]}"
echo "---- Unescaped content"
printf '<<%s>>\n' "${array[@]}"
此演示在两个方向上传递了潜在的恶意数据,并演示了它在不受损害的往返过程中仍然可以生存。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.