Chapter 16: Security and Best Practices
Shell scripts are powerful because they have direct access to system resources. However, this power makes them a prime target for attackers. A single unquoted variable or a missing input check can lead to total system compromise. This final chapter covers the non-negotiable rules for writing production-grade scripts.
I. Preventing Command Injection
Command injection occurs when an attacker can sneak their own commands into your script through an unvalidated input.
The Danger of eval
The eval command is the most dangerous tool in the shell. It executes a string as code. Avoid it at all costs.
Unquoted Variable Injection
# VULNERABLE:
# If user enters "; rm -rf /", the command becomes "ls ; rm -rf /"
read -p "Enter filename: " FILE
ls $FILE
# SECURE:
# The shell treats the input as a single literal string argument.
ls "$FILE"
II. Secure Secret Management
Never hardcode passwords, API keys, or database credentials directly in your script.
1. The Environment Method (Standard)
Pass secrets as environment variables that are set by your CI/CD system or secret manager (like Vault or AWS Secrets Manager).
# Load from environment
DB_PASS="${DATABASE_PASSWORD:?Error: DB password not set}"
2. The File Method (More Secure)
Store the secret in a file with restricted permissions (chmod 600) and read it into a variable.
DB_PASS=$(< /run/secrets/db_password)
III. Input Sanitization and Validation
Always verify that data matches the expected format before processing it.
IV. Automated Auditing: shellcheck
ShellCheck is a static analysis tool that finds bugs and security holes in your scripts. It is the gold standard for shell script development.
# Install ShellCheck
sudo apt install shellcheck
# Audit your script
shellcheck my_script.sh
It will catch common errors like:
- Missing quotes around variables.
- Inconsistent use of
[ ]and[[ ]]. - Useless use of
cat. - Potential command injection points.
V. Temporary Files and Directories
Never create temporary files in shared directories like /tmp with predictable names (e.g., /tmp/myscript.log). This leads to "Race Condition" vulnerabilities.
Use mktemp to create unique, secure temporary files.
# Create a unique temp file
TEMP_FILE=$(mktemp)
# Ensure it is deleted on exit
trap 'rm -f "$TEMP_FILE"' EXIT
VI. Final Summary: The Shell Master's Checklist
- Shebang: Always start with
#!/usr/bin/env bash. - Strict Mode: Use
set -euo pipefail. - Quoting: Quote every variable, every time.
- Scoping: Use
localfor all variables inside functions. - Logging: Redirect
stdoutandstderrto a log file. - Linting: Run
shellcheckbefore every commit.
Congratulations! You have completed the comprehensive Shell Scripting course. You are now equipped to build professional, secure, and highly efficient automation systems.
Happy Scripting!