【问题标题】:Prevent directory traversal vulnerability in bash script防止 bash 脚本中的目录遍历漏洞
【发布时间】:2020-06-25 13:14:29
【问题描述】:

如何防止 bash 脚本中的目录遍历攻击,其中参数包含目录名称?

例子:

$STAGE=$1
$APP=$2
deploy.sh dist/ /opt/apps/"$STAGE"/"$APP"

$STAGE$APP 变量是从外部设置的。攻击者可以使用".." 将其更改为任意路径。

我知道通常的解决方案是将目录字符串与返回绝对路径的函数的结果进行比较。但我找不到现成的解决方案,也不想提出自己的解决方案。

【问题讨论】:

    标签: bash directory-traversal


    【解决方案1】:

    这样的?

    #! /bin/bash
    
    STAGE=$1
    APP=$2
    
    expectedParentDir="/opt/apps/"
    
    function testDir(){
      arg=$1
      if [[ ! -f $arg ]]
      then
          echo "File $arg does not exist."
          exit 1
      fi
      rpath=$(realpath $arg)
      if [[ $rpath != ${expectedParentDir}* ]]
      then
       echo "Please only reference files under $expectedParentDir directory."   
       exit 2
      fi
    }
    
    testDir /opt/apps/"$STAGE"/"$APP"
    
    ... deploy ...
    

    示例调用

    test.sh "../../etc/" "passwd"
    Please only reference files under /opt/apps/ directory.
    ------------
    test.sh "../../etc/" "secret"
    File /opt/apps/../../etc//secret does not exist.
    
    1. 使用-f 测试文件是否存在,如果目标必须是目录,则使用-d
    2. 使用realpath解析路径
    3. 使用== ${expectedParentDir}* 确定解析的路径是否以预期字符串开头

    【讨论】:

      【解决方案2】:

      脚本应以仅有权访问必要目录的用户身份运行。

      【讨论】:

      • 是的。这只是一项额外的安全措施
      • 它是自动构建设置 (CI) 的一部分。 CI-runner 用户不能更改。为了避免漏洞,CI-runner 只能通过 sudo 以其他用户身份运行单个部署脚本。 (该单个脚本有一个特殊的规则 sudo 规则)。但是我们想要参数来控制目标目录。而且这些不应该允许目录遍历攻击
      • 这个建议可能不足以阻止一般的目录遍历。在只读情况下,当前用户可能可以读取大量有趣的文件。
      猜你喜欢
      • 2011-05-11
      • 2019-04-14
      • 2022-10-06
      • 1970-01-01
      • 2021-10-24
      • 1970-01-01
      • 2017-08-01
      • 2015-01-20
      • 2011-08-05
      相关资源
      最近更新 更多