Programming and Scripting for Cybersecurity: Part 1, Auditing Backup Bash Scripts
- Published on
- • 4 mins read•--- views
Introduction
When a security team needs to automate quickly, Bash remains a dependable ally. This lesson opens the Programming and Scripting for Cybersecurity series with two short backup scripts taken from the fictional company Dharma. By analysing the baseline script and its improved successor, we uncover the building blocks of shell automation, identify weaknesses, and outline concrete upgrades that make day-to-day operations safer.
Learning Objectives
- Recognize the core elements that shape a Bash script (shebang, commands, variables, exit codes, conditionals).
- Explain why scripting is an appropriate solution for lightweight, recurring administrative tasks.
- Compare a minimal script with a hardened variant and describe how each enhancement improves reliability or security.
- Propose next steps to evolve the scripts toward production-grade automation.
Scenario: automating safeguards at Dharma
Dharma's infrastructure group is rolling out process automation. Junior analysts are asked to audit existing scripts before modifying them, ensuring they understand every instruction that protects critical data. The team starts with a simple copy operation that runs after-hours. From there, they iterate, adding safety nets without sacrificing the agility that Bash provides.
Script 1: establishing the baseline
The first script is deliberately concise. It mirrors what many teams schedule in cron during the early stages of automation.
#!/bin/bash
# Copy file "usuarios" to specified path (create backup)
cp /home/dharma/usuarios.txt /home/dharma/backup/
# If exit code of last command is 0 (which means success), print notification message
if [ $? -eq 0 ]; then
echo "Backup completed successfully."
fi
How the script works
The shebang #!/bin/bash pins the interpreter, so the script behaves the same way even when something else invokes it from a different shell. The cp line performs the whole backup in one statement, which assumes the destination directory already exists and that the account running it has the privileges to write there. The $? check then reads the return code: zero means the copy succeeded, anything else means it failed, and the conditional prints a confirmation only in the first case.
Why Bash fits the job
For a task this focused, Bash is a pragmatic choice:
- The script is easy to deploy, version, and adjust without recompilation.
- Cron integration is trivial; log output can be redirected to centralized monitoring.
- Dependencies are minimal. Dharma's analysts can iterate immediately while building institutional knowledge of shell scripting.
Script 2: raising the bar
After the baseline proved valuable, Dharma invested in a safer version that captures lessons from production incidents.
#!/bin/bash
SOURCE_FILE="some/path/to/file.txt"
DESTINATION="/home/dharma/backup"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
TARGET_FILE="${DESTINATION}/users_backup_${TIMESTAMP}.txt"
mkdir -p "$DESTINATION"
cp "$SOURCE_FILE" "$TARGET_FILE" 2> /dev/stderr
if [ $? -eq 0 ]; then
echo "Backup completed successfully: $TARGET_FILE"
else
echo "Backup failed" >&2
fi
What Improved?
Explicit variables (SOURCE_FILE, DESTINATION) make the script self-documenting and simpler to point at a different environment. TIMESTAMP stops each run from overwriting the previous backup, which is what makes historical audits possible at all. mkdir -p prepares the destination when it is missing, so the first run succeeds instead of failing on a path that nobody created yet. And redirecting cp errors to stderr keeps failure messages reaching monitoring while success messages stay on stdout.
Opportunities for further hardening
Even this improved script leaves room for best practices that every security-minded engineer should consider:
- Replace the manual
$?test withif cp "$SOURCE_FILE" "$TARGET_FILE"; then … fi, which ties the success branch directly to the copy and exits early on failure. - Add a rotation routine (
findwith-mtime, orlogrotate) so backup files stop consuming disk space without a bound. - Introduce a lock file, or use
flock, to prevent overlapping runs that could corrupt the result. - Generate SHA-256 hashes for archived copies and store them somewhere tamper-resistant, so illicit modifications become detectable.
- Sync the backup to at least one additional system, better yet to several providers in different jurisdictions, to survive a local disaster.
Key Takeaways
- Foundational Bash features (shebangs, exit codes, and conditionals) form the backbone of automation and must be mastered before tackling advanced workflows.
- Clear variable names and defensive directory creation dramatically improve a script's readability and resilience.
- Simple improvements such as log separation, rotation policies, and mutual exclusion safeguards deliver outsized benefits for operational stability.
- Scripting stops being a quick hack the moment it is engineered thoughtfully. At that point it becomes a trustworthy layer in the cybersecurity toolkit.
Armed with this analysis, new members of Dharma's automation team can reason about existing scripts, communicate risks, and plan incremental upgrades. The next part of the series will build upon these fundamentals to incorporate logging, argument parsing, and more sophisticated security checks.
Open for contract collaboration
I am available for contract-based collaboration. If you have an interesting project idea, schedule a call via Calendly.
Schedule a 30-min call