问题描述
给定一个来自不受信任来源的字符串,例如
MALICIoUS_INPUT="$(awk -F = '/^VERSION=/ {print $2}' /path/to/compromised/etc/os-release | head -n 1)"
是否可以只对该字符串应用纯 shell 引号删除(参见 Shell Command Language (IEEE Std 1003.1-2017) 和 Bash manual),即不进行变量扩展、算术扩展、命令替换等?
这是必需的,例如从 os-release 文件中解析字符串,而无需对文件进行 source
-ing。
输入 | 预期结果 |
---|---|
'\"' |
\" |
"\"" |
" |
'$foo${foo}$(pwd)$((1+2))' |
$foo${foo}$(pwd)$((1+2)) |
"$foo${foo}$(pwd)$((1+2))" |
$foo${foo}$(pwd)$((1+2)) |
解决方法
比较 Reading quoted/escaped arguments correctly from a string 上已有答案对此问题的适用性:
parse_with_xargs() {
xargs printf '%s\0' <<<"$*"
}
parse_with_python() {
python -c '
import shlex,sys
for item in shlex.split(sys.stdin.read()):
sys.stdout.write(item + "\0")
' <<<"$*"
}
readarray -t example_lines <<'EOF'
'\"'
"\""
'$foo${foo}$(pwd)$((1+2))'
"$foo${foo}$(pwd)$((1+2))"
EOF
for line in "${example_lines[@]}"; do
printf 'Input line: %s\n' "$line"
printf 'Parsed with xargs: '; parse_with_xargs "$line" 2>&1; echo
printf 'Parsed with python: '; parse_with_python "$line" 2>&1; echo
echo
done
输出:
Input line: '\"'
Parsed with xargs: \"
Parsed with python: \"
Input line: "\""
Parsed with xargs: xargs: unmatched double quote; by default quotes are special to xargs unless you use the -0 option
Parsed with python: "
Input line: '$foo${foo}$(pwd)$((1+2))'
Parsed with xargs: $foo${foo}$(pwd)$((1+2))
Parsed with python: $foo${foo}$(pwd)$((1+2))
Input line: "$foo${foo}$(pwd)$((1+2))"
Parsed with xargs: $foo${foo}$(pwd)$((1+2))
Parsed with python: $foo${foo}$(pwd)$((1+2))