Search code examples
bashvalidationfilenames

How to validate filename in bash script?


A little bit about my application:

I am writing a small application in bash script. The application must store personal settings to home directory.

My settings are in the form of a key/value pair which will be stored as filename/content:

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

My current solution for adding a key/value:

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

What is the simplest and safe way to validate $KEY?

  • A built-in function?
  • A regular expression?

I really need a reusable solution, not just for this application.

Edit:

"validate filename" mean check string for proper filename format, accepted by OS.

  • "bob" : good filename format
  • "" : bad because filename can not be empty
  • "*" : ?
  • "/" : ?
  • "con" : ? ....

Solution

  • The only way to make something secure is to use a whitelist. Which means instead of blacklisting bad characters you allow good ones. The reason why blacklists will always fail is that you can't blacklist all of the weird characted, you'd always forget something. Especially if you're working with unicode strings.

    Filenames could contain anything. According to wikipedia:

    Ext4 Allowed characters in filenames: All bytes except NUL ('\0') and '/'

    Which means that whole bash scripts could be valid filenames. So, if I were you, I would only allow a-zA-Z as valid characters. Problem solved.

    That's how you do it:

    # 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