如何在bash中跳过3级(su命令,psql,然后查询)

时间:2018-06-15 13:07:38

标签: bash escaping psql su

我正在处理一个用于在服务器上安装应用程序的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附近添加引号,它就不再起作用了。我尝试了其他解决方案,但都没有工作。

有什么想法吗?

由于

1 个答案:

答案 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/有其原始来源。