From 6e800abefcdc9842ce9d049cd4bec4292e2ab8e9 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 05:06:49 +0000 Subject: [PATCH] chore(backup): enforce secure permissions and fix arg injection - Explicitly set chmod 700 on backup and log directories to prevent unauthorized access. - Use umask 077 when creating zip archives to ensure they are readable only by the owner (0600). - Refactor zip exclusion handling to use bash arrays ("${exclude_args[@]}") instead of string splitting, fixing potential argument injection and issues with spaces in filenames. - Remove obsolete `build_exclude_args` function. Co-authored-by: kidchenko <5432753+kidchenko@users.noreply.github.com> --- tools/backup-projects.sh | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/tools/backup-projects.sh b/tools/backup-projects.sh index 1b7f6d2..eb4dac4 100755 --- a/tools/backup-projects.sh +++ b/tools/backup-projects.sh @@ -232,15 +232,6 @@ parse_args() { done } -# --- Build Exclude Arguments for Zip --- -build_exclude_args() { - local args=() - for pattern in "${EXCLUDE_PATTERNS[@]}"; do - args+=("-x" "*/${pattern}/*" "-x" "*/${pattern}") - done - echo "${args[@]}" -} - # --- Git Sync --- sync_git_repos() { say "Syncing git repositories..." @@ -351,10 +342,12 @@ cmd_backup() { # Setup directories if [[ "$DRY_RUN" != true ]]; then mkdir -p "$BACKUP_TEMP_DIR" + chmod 700 "$BACKUP_TEMP_DIR" mkdir -p "$LOG_DIR" + chmod 700 "$LOG_DIR" else - debug "Would create: $BACKUP_TEMP_DIR" - debug "Would create: $LOG_DIR" + debug "Would create: $BACKUP_TEMP_DIR (chmod 700)" + debug "Would create: $LOG_DIR (chmod 700)" fi # Sync git repositories first @@ -406,17 +399,21 @@ cmd_backup() { done fi else - local exclude_args - exclude_args=$(build_exclude_args) + # Build exclude arguments as an array to handle spaces correctly + local exclude_args=() + for pattern in "${EXCLUDE_PATTERNS[@]}"; do + exclude_args+=("-x" "*/${pattern}/*" "-x" "*/${pattern}") + done ( cd "$HOME" || exit 1 + # Set umask to ensure archive is not world-readable (0600) + umask 077 + if [[ "$VERBOSE" == true ]]; then - # shellcheck disable=SC2086 - zip -r "$archive_path" "${relative_paths[@]}" $exclude_args + zip -r "$archive_path" "${relative_paths[@]}" "${exclude_args[@]}" else - # shellcheck disable=SC2086 - zip -r -q "$archive_path" "${relative_paths[@]}" $exclude_args + zip -r -q "$archive_path" "${relative_paths[@]}" "${exclude_args[@]}" fi ) @@ -427,7 +424,7 @@ cmd_backup() { local archive_size archive_size=$(du -h "$archive_path" | cut -f1) - say "Archive created: $archive_size" + say "Archive created: $archive_size (permissions: 0600)" fi # Upload to remote (only if --upload flag is provided)