4

关于我的应用程序的一点点:

我正在用 bash 脚本编写一个小应用程序。应用程序必须将个人设置存储到主目录。

我的设置采用键/值对的形式,将存储为文件名/内容:

for example:
~/my-github-app
    ├── github-account
    ├── github-token

我当前添加键/值的解决方案:

read KEY
read VALUE
# FIXME! should check for for valid filename.
#        user can do injection hack by KEY="../../path/to/yourfile"
echo $VALUE > ~/my-github-app/$KEY

验证 $KEY 的最简单和安全的方法是什么?

  • 内置函数?
  • 正则表达式?

我真的需要一个可重用的解决方案,而不仅仅是这个应用程序。

编辑:

“验证文件名”是指检查字符串以确保操作系统接受的正确文件名格式。

  • "bob" : 好的文件名格式
  • "" : 不好,因为文件名不能为空
  • “*”:?
  • “/”:?
  • “骗局”:?……
4

4 回答 4

8

确保安全的唯一方法是使用白名单。这意味着不要将坏字符列入黑名单,而是允许好字符。黑名单总是失败的原因是你不能把所有奇怪的字符都列入黑名单,你总是会忘记一些东西。特别是如果您正在使用 unicode 字符串。

文件名可以包含任何内容。根据维基百科:

Ext4 文件名中允许的字符:除 NUL ('\0') 和 '/' 之外的所有字节

这意味着整个 bash 脚本可能是有效的文件名。所以,如果我是你,我只会允许 a-zA-Z 作为有效字符。问题解决了。

这就是你的做法:

# if [[ $key =~ [^a-zA-Z] ]]; then # or this. Whatever makes more sense to you
if ! [[ $key =~ ^[a-zA-Z]+$ ]]; then
    echo 'Wrong key. Only a-zA-Z characters are allowed' >&2 # write to stderr
    exit 1
fi
于 2013-08-20T00:50:39.643 回答
4

除了@Aleks-Daniel Jakimenko-A. 的回答之外,以下脚本还会检查以下条件,如果设置了所有条件,则True返回:

  • a-z
  • A-Z
  • 0-9
  • 下划线 ( _)
  • 破折号 ( -)
  • 期间 ( .)
  • 最大长度为 255
  • 第一个字符应该是字符或数字:{ a-zor A-zor 0-9}

my_script.sh:

#!/bin/bash
# To run: bash my_script.sh <my_string_is>

key=$1
val=$(echo "${#key}")

if [[ $key == "" ]]; then
   echo "False";
   exit
fi

if [[ $key == "." ]] || [[ $key == ".." ]]; then
    # "." and ".." are added automatically and always exist, so you can't have a
    # file named . or .. // https://askubuntu.com/a/416508/660555
    echo "False";
    exit
fi

if [ $val -gt 255 ]; then
   # String's length check
   echo "False";
   exit
fi

if ! [[ $key =~ ^[0-9a-zA-Z._-]+$ ]]; then
    # Checks whether valid characters exist
    echo "False";
    exit
fi

_key=$(echo $key | cut -c1-1)
if ! [[ $_key =~ ^[0-9a-zA-Z.]+$ ]]; then
    # Checks the first character
    echo "False";
    exit
fi

echo "True";
于 2018-04-14T14:28:51.153 回答
1

如果您只想检查文件是否已经存在,请使用该test命令并像这样使用它进行验证:

if [[ ! -e "$KEY" ]]
then
    #file doet not exists
fi
于 2013-08-16T22:59:04.133 回答
0

您要验证什么,只是密钥不包含任何路径信息?

KEY=$(basename $KEY) 

这将删除作为路径一部分的 KEY 的任何部分。也就是说,有很多用户可以输入的东西可能是个坏主意。您是否可以列出允许的密钥,然后拒绝不在该列表中的任何内容?

如果您尝试查看文件是否可写,您可以检查 a) 它是否存在且可写 ( -w) 或 b) 尝试写入并检查错误。

于 2013-08-16T22:21:29.303 回答