Reputation: 3259
How can I prevent directory traversal attacks in a bash script, where arguments contain directory names?
Example:
$STAGE=$1
$APP=$2
deploy.sh dist/ /opt/apps/"$STAGE"/"$APP"
The $STAGE
and $APP
variables are set from outside. An attacker could change this to an arbitrary path with ".."
.
I know the usual solution is to compare the directory string with the result of a function that returns the absolute path. But I couldn't find a ready solution and don't want to come up with my own.
Upvotes: 3
Views: 1416
Reputation: 9588
Something like this?
#! /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 ...
Example Call
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
or use -d
if target must be a directoryrealpath
to resolve path== ${expectedParentDir}*
to find out if resolved path starts with expected stringUpvotes: 1
Reputation: 12027
The script should be run as a user that only has permissions to access the necessary directories.
Upvotes: -1