我正在处理一个用于在服务器上安装应用程序的bash脚本,并为该应用程序创建一个postgresql用户。
问题是,如果用户包含特殊字符,则不会对其进行转义。所以我想在查询中转义名称。
以下是我的代码的一部分:
userdata
所以我必须逃脱:
db_user="test-test"
db_password=1234
su - postgres -c "psql -c \"CREATE USER $db_user WITH PASSWORD '$db_password';\""
su -c ...
psql -c ...
$db_user
当然,如果我在$ db_user附近添加引号,它就不再起作用了。我尝试了其他解决方案,但都没有工作。
有什么想法吗?
由于
答案 0 :(得分:0)
让shell为您完成工作。在这种情况下,这意味着printf '%q'
- 返回每个文字参数的eval
- 安全版本。
cmd=( psql -c "CREATE USER $db_user WITH PASSWORD '$db_password';" )
printf -v cmd_q '%q ' "${cmd[@]}"
su - postgres -c "$cmd_q"
顺便说一句,用这种方式将文字文本替换成SQL查询是非常不安全的 - 但是如果你按照上面的过程进行操作,你只会出现SQL注入错误,而不是shell注入错误。
为了避免SQL注入错误,您希望避免将值文本替换为查询。
# This is inefficient, but makes it completely unambiguous that our heredocs are literal
query=$(cat <<'EOF'
CREATE USER :new_user_name WITH PASSWORD :'new_user_password';
EOF
)
cmd=(
psql \
--set=new_user_name="$db_user" \
--set=new_user_password="$db_password"
-c "$query"
)
printf -v cmd_q '%q ' "${cmd[@]}"
su - postgres -c "$cmd_q"
有关此技术的更多信息,请参阅http://caryrobbins.com/dev/postgres-scripting/。标题中链接的经典XKCD(也是原始代码冒险的具体例子!)在https://xkcd.com/327/有其原始来源。