防止bash脚本中的目录遍历漏洞

防止bash脚本中的目录遍历漏洞,bash,directory-traversal,Bash,Directory Traversal,在参数包含目录名的bash脚本中,如何防止目录遍历攻击 例如: $STAGE=$1 $APP=$2 deploy.sh dist/ /opt/apps/"$STAGE"/"$APP" $STAGE和$APP变量是从外部设置的。攻击者可以使用“”将其更改为任意路径。“ 我知道通常的解决方案是将目录字符串与返回绝对路径的函数的结果进行比较。但是我找不到现成的解决方案,也不想提出我自己的解决方案。脚本应该以只有访问必要目录的权限的用户身份运行。类似这样的情况

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

例如:

$STAGE=$1
$APP=$2
deploy.sh dist/ /opt/apps/"$STAGE"/"$APP"
$STAGE
$APP
变量是从外部设置的。攻击者可以使用“
”将其更改为任意路径。“


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

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

类似这样的情况

#! /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.
  • 使用
    -f
    测试文件是否存在,如果目标必须是目录,则使用
    -d
  • 使用
    realpath
    解析路径
  • 使用
    =${expectedParentDir}*
    确定解析的路径是否以预期字符串开头

  • 它是。这只是一个额外的安全措施,它是自动生成设置(CI)的一部分。无法更改CI运行程序用户。为避免漏洞,CI runner只能通过sudo作为其他用户运行单个部署脚本。(对于单个脚本,有一个特殊的sudo规则)。但是我们需要参数来控制目标目录。而且这些不应允许目录遍历攻击。通常,此建议可能不足以防止目录遍历。在只读的情况下,当前用户可以读取大量的插入文件。