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

  • Shebang (#!/bin/bash) – Pins the interpreter so the script runs consistently, even if invoked from another shell.
  • Copy command (cp …) – Performs the full backup operation in one line. It assumes the destination directory exists and that the executing account has sufficient privileges.
  • Exit status check ($?) – Reads the return code of cp. A zero status indicates success; a non-zero status means failure. The conditional prints a confirmation when everything works.

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?

  • Parameterised paths. Explicit variables (SOURCE_FILE, DESTINATION) make the script self-documenting and simpler to adjust for different environments.
  • Timestamped artefacts. TIMESTAMP prevents overwriting previous backups and supports historical audits.
  • Resilient setup. mkdir -p prepares the destination if it is missing, enabling first-run success.
  • Error-channel separation. Redirecting cp errors to stderr ensures failure messages reach monitoring systems, 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:

  • Inline command evaluation. Replace the manual $? test with if cp "$SOURCE_FILE" "$TARGET_FILE"; then … fi to tie success logic directly to the copy command and exit early on failure.
  • Retention policy. Add a rotation routine (find + -mtime, or logrotate) so backup files do not consume unlimited disk space.
  • Concurrency guard. Introduce a lock file or use flock to prevent overlapping runs that could corrupt results.
  • Integrity checks. Generate SHA-256 hashes for archived copies and store them in a tamper-resistant location to detect illicit modifications.
  • Redundant storage. Sync the backup to at least one additional system—even better, to multiple providers across jurisdictions—to mitigate local disasters.

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 is not merely a quick hack; when engineered thoughtfully, 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.