/bin/bash - Proper Whitespace Handling - Whitespace Safety - End-of-Options Parameter Security

From Kicksecure
< Dev
Jump to navigation Jump to search

Supporting multiple command line parameters with spaces in wrapper scripts and End-of-Options Parameter (--) for better security.

safe echo[edit]

TODO

shellcheck bug reports:

helper-scripts:

A drop-in replacement safe_echo would be useful to have.

Based on echo:

  • implementation: abort if first character is a -
  • advantage: supports colors etc.
  • disadvantage: break on legitimate output such as "--example"

Based on printf:

  • disadvantage: no support for colors etc.
  • advantae: does not break if first character is -

Bash Proper Whitespace Handling[edit]

#!/bin/bash

## https://yakking.branchable.com/posts/whitespace-safety/

set -e

app_user=user
lib_dir="/tmp/test/lib/program with space/something spacy"
main_app_dir="/tmp/test/home/user/folder with space/abc"
mkdir -p "$lib_dir"
mkdir -p "$main_app_dir"

declare -a cmd

cmd+=("cp")
cmd+=("-r")
cmd+=("${lib_dir}")
cmd+=("${main_app_dir}/")

"${cmd[@]}"

Use of End-of-Options Parameter (--)[edit]

The end-of-options parameter "--" is crucial because otherwise inputs might be mistaken for command options. This might even be a security risk. Here are examples using the `sponge` command:

echo test

Result: OK. This works because "testfilename" doesn't look like an option.

echo test

Result: Fail. The command interprets "--testfilename" as a series of options:

sponge: invalid option -- '-'
sponge: invalid option -- 't'
sponge: invalid option -- 'e'
...
test

echo test

Result: OK. The `--` signals that "--testfilename" is a filename, not an option.

Conclusion:

  • The "--" parameter marks the end of command options.
  • Use "--" add the end of a command prevent misinterpretation.
  • This technique is applicable to many Unix/Linux commands, not just sponge.

nounset - Check if Variable Exists[edit]

#!/bin/bash

set -x
set -e
set -o nounset

## Enable for testing.
#unset HOME

if [ -z "${HOME+x}" ]; then
    echo "Error: HOME is not set."
fi

echo "$HOME"

Safely Using Find with End-Of-Options[edit]

Example:

Note: Variable could be different. Could be for example --/usr.

folder_name="/usr"

printf '%s' "${folder_name}" | find -files0-from - -perm /u=s,g=s -print0

Of if safe_echo_nonewline is available from helper-scripts.

# shellcheck disable=SC1091 source /usr/libexec/helper-scripts/safe_echo.sh safe_echo_nonewline "${folder_name}" | find -files0-from - -perm /u=s,g=s -print0

Not using bash's built-in echo, because it does not support end-of-options ("--").

Not using /usr/bin/echo, because it does not support end-of-options ("--").

## Broken! ## The '-n' option is needed to avoid piping a newline to 'find'. echo -n -- "${folder_name}" | find -files0-from - -perm /u=s,g=s -print0

misc[edit]

base_name="${file_name##*/}"
file_extension="${base_name##*.}"

coding style[edit]

  • use:
    • shellcheck
    • safe-rm
    • scurl
    • str_replace
    • append-once
  • use ${variable} style
  • use shell options
set -o errexit
set -o nounset
set -o errtrace
set -o pipefail

See Also[edit]

We believe security software like Kicksecure needs to remain Open Source and independent. Would you help sustain and grow the project? Learn more about our 12 year success story and maybe DONATE!