代码之家  ›  专栏  ›  技术社区  ›  asmaier

如何防止bash脚本中的代码/选项注入

  •  3
  • asmaier  · 技术社区  · 15 年前

    我编写了一个名为“isinfile.sh”的小型bash脚本,用于检查给定给脚本的第一个术语是否可以在文件“file.txt”中找到:

    #!/bin/bash
    
    FILE="file.txt"
    
    if [ `grep -w "$1" $FILE` ]; then 
     echo "true"
    else
     echo "false"
    fi
    

    但是,像这样运行脚本

    > ./isinFile.sh -x
    

    中断脚本,因为 -x 由解释 grep 作为一种选择。 所以我改进了我的剧本

    #!/bin/bash
    
    FILE="file.txt"
    
    if [ `grep -w -- "$1" $FILE` ]; then 
     echo "true"
    else
     echo "false"
    fi
    

    使用 -- 作为grep的论点。现在运行

    > ./isinFile.sh -x
    false
    

    作品。但正在使用 —— 在bash脚本中防止代码/选项注入的正确且唯一的方法是什么?我在野外没有见过它,只是在 ABASH: Finding Bugs in Bash Scripts .

    3 回复  |  直到 15 年前
        1
  •  2
  •   ShinTakezou    15 年前
    grep -w -- ...

    阻止以下解释--

    编辑

    (我没有读最后一部分对不起)。是的,这是唯一的办法。另一种方法是避免将其作为搜索的第一部分;例如 ".{0}-x" 也可以,但很奇怪,例如

    grep -w ".{0}$1" ...

    也应该有效。

        2
  •  2
  •   Gordon Davisson    15 年前

    在这个脚本中,实际上还有另一个代码注入(或者你想称之为什么)错误:它只处理 grep [ (阿卡 test )命令,并假定它不为空时将返回true。但如果输出的长度超过一个“字”的话, [ 将其视为表达式并尝试对其进行计算。例如,假设文件包含行 0 -eq 2 你搜索“0”-- [ 将决定0不等于2,并且脚本将打印false,尽管它找到了匹配项。

    解决这一问题的最佳方法是使用Ignacio Vazquez Abrams的建议(如Dennis Williamson所阐明的),这完全避免了解析问题,而且速度更快(因为 -q 使 格雷普 停止搜索第一个匹配项)。如果该选项不可用,另一种方法是用双引号保护输出: if [ "$(grep -w -- "$1" "$FILE")" ]; then (请注意,我还使用了$()而不是反引号',因为我发现它们更容易阅读,并且在$file周围加引号,以防它包含任何有趣的内容,如空格)。

        3
  •  1
  •   Dennis Williamson    15 年前

    虽然在这种特殊情况下不适用,但是可以使用另一种技术来防止以连字符开头的文件名被解释为选项:

    rm ./-x
    

    rm /path/to/-x
    
    推荐文章