From c380476cd257c03ba830c3900f1fb9c19bee0268 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 04:43:22 +0000 Subject: [PATCH] fix: Secure backup file permissions (chmod 600/700) Explicitly set `umask 077` and use `chmod` to ensure backup archives and directories are private (600/700). Added a regression test `tests/verify_backup_permissions.sh`. Co-authored-by: kidchenko <5432753+kidchenko@users.noreply.github.com> --- .jules/sentinel.md | 4 ++ tests/verify_backup_permissions.sh | 73 ++++++++++++++++++++++++++++++ tools/backup-projects.sh | 6 +++ 3 files changed, 83 insertions(+) create mode 100644 .jules/sentinel.md create mode 100755 tests/verify_backup_permissions.sh diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000..4c40b86 --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2024-05-24 - Secure Backup Permissions +**Vulnerability:** Backup archives created by `zip` without explicit permissions were world-readable (depending on umask), exposing sensitive project data. +**Learning:** `mkdir -p` and `zip` respect the process `umask`, but relying on system defaults is insecure for sensitive data. +**Prevention:** Explicitly set `umask 077` at the start of sensitive operations and use `chmod` to enforce restrictive permissions (600/700) on critical artifacts. diff --git a/tests/verify_backup_permissions.sh b/tests/verify_backup_permissions.sh new file mode 100755 index 0000000..b579ae2 --- /dev/null +++ b/tests/verify_backup_permissions.sh @@ -0,0 +1,73 @@ +#!/bin/bash +set -e + +# Setup test paths +TEST_DIR="$(mktemp -d)" +TEST_SOURCE="$TEST_DIR/source" +TEST_BACKUP_DIR="$TEST_DIR/backups" +TEST_CONFIG="$TEST_DIR/config.yaml" +SCRIPT_PATH="$(pwd)/tools/backup-projects.sh" + +# Cleanup on exit +trap 'rm -rf "$TEST_DIR"' EXIT + +# Create source directory with a file +mkdir -p "$TEST_SOURCE" +echo "sensitive data" > "$TEST_SOURCE/secret.txt" + +# Create config file +cat > "$TEST_CONFIG" </dev/null + +# Check backup file permissions +BACKUP_FILE=$(find "$TEST_BACKUP_DIR" -name "*.zip" | head -n 1) + +if [[ -z "$BACKUP_FILE" ]]; then + echo "Backup file not found!" + exit 1 +fi + +if [[ "$(uname -s)" == "Darwin" ]]; then + PERMS=$(stat -f "%Lp" "$BACKUP_FILE") + DIR_PERMS=$(stat -f "%Lp" "$TEST_BACKUP_DIR") +else + PERMS=$(stat -c "%a" "$BACKUP_FILE") + DIR_PERMS=$(stat -c "%a" "$TEST_BACKUP_DIR") +fi +echo "Backup file permissions: $PERMS" +echo "Backup directory permissions: $DIR_PERMS" + +FAILED=0 + +# Verify if permissions are secure (600 for file, 700 for directory) +if [[ "$PERMS" != "600" ]]; then + echo "FAIL: Backup file permissions are not 600" + FAILED=1 +else + echo "PASS: Backup file permissions are 600" +fi + +if [[ "$DIR_PERMS" != "700" ]]; then + echo "FAIL: Backup directory permissions are not 700" + FAILED=1 +else + echo "PASS: Backup directory permissions are 700" +fi + +exit $FAILED diff --git a/tools/backup-projects.sh b/tools/backup-projects.sh index 1b7f6d2..bbfbb78 100755 --- a/tools/backup-projects.sh +++ b/tools/backup-projects.sh @@ -350,7 +350,10 @@ cmd_backup() { # Setup directories if [[ "$DRY_RUN" != true ]]; then + # Ensure secure permissions for backup directory (700) + umask 077 mkdir -p "$BACKUP_TEMP_DIR" + chmod 700 "$BACKUP_TEMP_DIR" mkdir -p "$LOG_DIR" else debug "Would create: $BACKUP_TEMP_DIR" @@ -425,6 +428,9 @@ cmd_backup() { return 1 fi + # Ensure secure permissions for backup archive (600) + chmod 600 "$archive_path" + local archive_size archive_size=$(du -h "$archive_path" | cut -f1) say "Archive created: $archive_size"