【问题标题】:Variable not expanding in Double quotes for bash script变量未在 bash 脚本的双引号中扩展
【发布时间】:2020-01-13 17:02:38
【问题描述】:

我有一个 bash 脚本,我试图在其中调用一个以变量值作为输入的 curl。尝试执行 bash 脚本时,变量值没有在双引号中展开。

变量扩展后脚本中的预期卷曲应该如下:

/usr/bin/curl -s -vvvv http://hmvddrsvr:8044/query/service -u iamusr:pssd -d 'statement=DELETE FROM `test_bucket` WHERE type = "Metadata" AND market = "ES" AND status = "active" AND meta(test_bucket).id="fgsd34sff334" '

在调试模式下观察时执行如下:

/usr/bin/curl -s -vvvv http://hmvddrsvr:8044/query/service -u iamusr:pssd -d 'statement=DELETE FROM `test_bucket` WHERE type = "Metadata" AND market = "ES" AND status = "active" AND meta(test_bucket).id=\""$idp_sub"\" '

我的 bash 脚本如下:

#!/bin/bash

idp_sub=""


for idp_sub in $(cat /opt/SP/jboss/home/mayur/es_idp_sub.txt)

do

/usr/bin/curl -s -vvvv http://hmvddrsvr:8044/query/service -u iamusr:pssd -d 'statement=DELETE FROM `test_bucket` WHERE type = "Metadata" AND market = "ES" AND status = "active" AND meta(test_bucket).id=\""$idp_sub"\" ' -o  /opt/SP/jboss/home/mayur/es_delete_response.txt


done

如何在双引号内扩展变量值,如上所示的预期输出?

【问题讨论】:

  • 不要使用字符串插值来构造 SQL 查询。使用具有适当 SQL 库的语言来创建参数化查询。
  • 至少,使用新语言的库来构建 URL 以确保您的查询正确地进行 URL 转义,此外还要确保生成的查询是有效且安全的 SQL。
  • 这里没有什么需要进行 URL 转义的;唯一的非常量部分在 -d 参数内,该参数将作为 application/x-www-form-urlencoded 发布。

标签: bash shell variables


【解决方案1】:

你的双引号字符串在单引号内,不会被扩展。

比较:

foo=bar
echo 'foo=\""$foo\"'
echo 'foo="'"$foo"'"'

在第二个示例中,我们结束单引号,并用双引号 $foo,然后为最后的 ' 开始新的单引号。

如果我们改为使用printf 扩展可能更容易阅读:

printf 'foo=%s\n' "$foo"

这是您可能希望作为进程替换运行的东西。

但是...

这是构造SQL查询的错误危险方式(而且网络服务器也很差,如果它转发任意查询 - 我希望它没有写数据的权限)。阅读“SQL 命令注入”并在了解问题后返回此代码。

【讨论】:

    【解决方案2】:

    单引号内的任何内容都不会被 bash 扩展,包括任何双引号和变量名。好消息是您可以结束单引号部分并立即开始一个双引号部分来引入变量,并且它将全部连接成应用程序的单个参数(curl)。试试:

    /usr/bin/curl -s -vvvv http://hmvddrsvr:8044/query/service -u iamusr:pssd -d 'statement=DELETE FROM `test_bucket` WHERE type = "Metadata" AND market = "ES" AND status = "active" AND meta(test_bucket).id=\"'"$idp_sub"'\" ' -o  /opt/SP/jboss/home/mayur/es_delete_response.txt
    

    您可以通过拒绝任何包含双引号的字符串来使您的代码具有很强的防注入性,但您可能会拒绝一些已合法转义的字符串。

    如果你可以使用 q 语法来引用字符串,你可以让它更防注入,但我猜攻击者只需注入]"

    /usr/bin/curl -s -vvvv http://hmvddrsvr:8044/query/service -u iamusr:pssd -d 'statement=DELETE FROM `test_bucket` WHERE type = "Metadata" AND market = "ES" AND status = "active" AND meta(test_bucket).id=q\"['"$idp_sub"]'\" ' -o  /opt/SP/jboss/home/mayur/es_delete_response.txt
    

    然后您可以搜索并拒绝模式字符串]" 作为您的反注入,这将允许更广泛的合法字符串类别。您必须告诉用户您已将 q[] 引用应用于他们的输入,因此他们不必这样做。

    【讨论】:

    • 请不要鼓励 SQL 注入漏洞。
    • @chepner 公平点,值得一提,但这是否真的是一个漏洞将取决于上下文。我想你会推荐一些这样的工具?
    • 我在对该问题的评论中提出了建议。对于具有如此根本性缺陷前提的问题,任何更具体的内容都只是一种意见。
    • 避免注入的一个非常基本的方法是拒绝包含引号的变量值。当然,我相信在现代 sql 中可以正确地转义引号。嗯,看起来很简单:q'[The 'end' of the day]'
    猜你喜欢
    • 2012-01-25
    • 2012-03-17
    • 1970-01-01
    • 2014-06-19
    • 2023-04-06
    • 1970-01-01
    • 2021-05-04
    • 1970-01-01
    • 2021-03-08
    相关资源
    最近更新 更多