Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Sentinel's Journal

## 2026-02-19 - Insecure Backup Permissions

Check failure on line 3 in .jules/sentinel.md

View workflow job for this annotation

GitHub Actions / Lint Documentation

Headings should be surrounded by blank lines

.jules/sentinel.md:3 MD022/blanks-around-headings Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "## 2026-02-19 - Insecure Backup Permissions"] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md022.md
**Vulnerability:** Backup archives containing sensitive project data were created with default `umask` (often 022), making them readable by other users on the system (`-rw-rw-r--`).

Check failure on line 4 in .jules/sentinel.md

View workflow job for this annotation

GitHub Actions / Lint Documentation

Line length

.jules/sentinel.md:4:81 MD013/line-length Line length [Expected: 80; Actual: 181] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md
**Learning:** Even in single-user systems, assuming default permissions are secure is risky. Tools creating sensitive artifacts must explicitly enforce restrictive permissions.

Check failure on line 5 in .jules/sentinel.md

View workflow job for this annotation

GitHub Actions / Lint Documentation

Line length

.jules/sentinel.md:5:81 MD013/line-length Line length [Expected: 80; Actual: 176] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md
**Prevention:** Added `umask 077` to `tools/backup-projects.sh` and explicitly `chmod 700` on backup directories to ensure least privilege.

Check failure on line 6 in .jules/sentinel.md

View workflow job for this annotation

GitHub Actions / Lint Documentation

Line length

.jules/sentinel.md:6:81 MD013/line-length Line length [Expected: 80; Actual: 139] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md
Comment on lines +3 to +6
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟑 Minor

Markdown violations are failing CI β€” fix before merge.

The Lint Documentation check reports two classes of failures:

  • MD022: no blank line after the ## heading (line 3)
  • MD013: lines 4–6 each exceed the 80-character limit
πŸ“ Proposed fix
 # Sentinel's Journal
 
 ## 2026-02-19 - Insecure Backup Permissions
+
-**Vulnerability:** Backup archives containing sensitive project data were created with default `umask` (often 022), making them readable by other users on the system (`-rw-rw-r--`).
-**Learning:** Even in single-user systems, assuming default permissions are secure is risky. Tools creating sensitive artifacts must explicitly enforce restrictive permissions.
-**Prevention:** Added `umask 077` to `tools/backup-projects.sh` and explicitly `chmod 700` on backup directories to ensure least privilege.
+**Vulnerability:** Backup archives containing sensitive project data were created with
+default `umask` (often 022), making them readable by other users (`-rw-rw-r--`).
+
+**Learning:** Even in single-user systems, assuming default permissions are secure is
+risky. Tools creating sensitive artifacts must explicitly enforce restrictive permissions.
+
+**Prevention:** Added `umask 077` to `tools/backup-projects.sh` and explicitly
+`chmod 700` on backup directories to ensure least privilege.
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## 2026-02-19 - Insecure Backup Permissions
**Vulnerability:** Backup archives containing sensitive project data were created with default `umask` (often 022), making them readable by other users on the system (`-rw-rw-r--`).
**Learning:** Even in single-user systems, assuming default permissions are secure is risky. Tools creating sensitive artifacts must explicitly enforce restrictive permissions.
**Prevention:** Added `umask 077` to `tools/backup-projects.sh` and explicitly `chmod 700` on backup directories to ensure least privilege.
## 2026-02-19 - Insecure Backup Permissions
**Vulnerability:** Backup archives containing sensitive project data were created with
default `umask` (often 022), making them readable by other users (`-rw-rw-r--`).
**Learning:** Even in single-user systems, assuming default permissions are secure is
risky. Tools creating sensitive artifacts must explicitly enforce restrictive permissions.
**Prevention:** Added `umask 077` to `tools/backup-projects.sh` and explicitly
`chmod 700` on backup directories to ensure least privilege.
🧰 Tools
πŸͺ› GitHub Check: Lint Documentation

[failure] 6-6: Line length
.jules/sentinel.md:6:81 MD013/line-length Line length [Expected: 80; Actual: 139] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md


[failure] 5-5: Line length
.jules/sentinel.md:5:81 MD013/line-length Line length [Expected: 80; Actual: 176] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md


[failure] 4-4: Line length
.jules/sentinel.md:4:81 MD013/line-length Line length [Expected: 80; Actual: 181] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md


[failure] 3-3: Headings should be surrounded by blank lines
.jules/sentinel.md:3 MD022/blanks-around-headings Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "## 2026-02-19 - Insecure Backup Permissions"] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md022.md

πŸ€– Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.jules/sentinel.md around lines 3 - 6, Add a blank line immediately after
the "## 2026-02-19 - Insecure Backup Permissions" heading and reflow the three
following sentences so none exceed 80 characters; specifically edit the
paragraph lines describing Vulnerability, Learning, and Prevention so each
logical sentence is wrapped to <=80 chars (or split into multiple lines) while
preserving wording (and keep the mention of adding `umask 077` and `chmod 700`
intact) to satisfy MD022 and MD013.

99 changes: 99 additions & 0 deletions tests/verify_backup_permissions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/bin/bash
set -e

# Setup test environment
# Use mktemp directory
TEST_DIR=$(mktemp -d 2>/dev/null || mktemp -d -t 'test_backup')
BACKUP_DIR="$TEST_DIR/backups"
SOURCE_DIR="$TEST_DIR/source"
CONFIG_FILE="$TEST_DIR/config.yaml"

mkdir -p "$SOURCE_DIR"
echo "secret" > "$SOURCE_DIR/secret.txt"

# Create config file
cat <<EOF > "$CONFIG_FILE"
backup:
folders:
- "$SOURCE_DIR"
local:
base_dir: "$BACKUP_DIR"
remote:
enabled: false
logging:
enabled: false
EOF

# Determine repo root
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BACKUP_SCRIPT="$REPO_ROOT/tools/backup-projects.sh"

echo "Running backup script: $BACKUP_SCRIPT"
# Run the backup command
# We ignore output to reduce noise, but capture errors if needed
bash "$BACKUP_SCRIPT" --config "$CONFIG_FILE" backup > "$TEST_DIR/backup.log" 2>&1 || {
echo "Backup script failed. Log:"
cat "$TEST_DIR/backup.log"
rm -rf "$TEST_DIR"
exit 1
}

# Check permissions
BACKUP_ARCHIVE=$(find "$BACKUP_DIR" -name "*.zip" | head -n 1)

if [[ ! -f "$BACKUP_ARCHIVE" ]]; then
echo "Backup failed: No archive created"
rm -rf "$TEST_DIR"
exit 1
fi

# Get permissions (Linux stat)
if stat --version 2>/dev/null | grep -q "GNU"; then
# GNU stat
PERMS=$(stat -c "%a" "$BACKUP_ARCHIVE")
DIR_PERMS=$(stat -c "%a" "$BACKUP_DIR")
elif stat --version 2>/dev/null; then
# Fallback for other stats that might support --version but not be GNU (unlikely)
PERMS=$(stat -c "%a" "$BACKUP_ARCHIVE")
DIR_PERMS=$(stat -c "%a" "$BACKUP_DIR")
else
# BSD stat (macOS) - stat --version usually fails on BSD stat
# Try BSD syntax
if stat -f "%Lp" "$BACKUP_ARCHIVE" >/dev/null 2>&1; then
PERMS=$(stat -f "%Lp" "$BACKUP_ARCHIVE")
DIR_PERMS=$(stat -f "%Lp" "$BACKUP_DIR")
else
# Fallback to GNU syntax if --version check failed but it is GNU
PERMS=$(stat -c "%a" "$BACKUP_ARCHIVE")
DIR_PERMS=$(stat -c "%a" "$BACKUP_DIR")
fi
fi

echo "Backup Archive Permissions: $PERMS"
echo "Backup Directory Permissions: $DIR_PERMS"

FAILED=0

# Check archive permissions (should be 600 or 400)
if [[ "$PERMS" != "600" && "$PERMS" != "400" ]]; then
echo "FAIL: Insecure archive permissions ($PERMS). Expected 600 or 400."
FAILED=1
else
echo "PASS: Archive permissions are secure."
fi

# Check directory permissions (should be 700)
if [[ "$DIR_PERMS" != "700" ]]; then
echo "FAIL: Insecure directory permissions ($DIR_PERMS). Expected 700."
FAILED=1
else
echo "PASS: Directory permissions are secure."
fi

rm -rf "$TEST_DIR"

if [[ $FAILED -eq 1 ]]; then
exit 1
fi

exit 0
3 changes: 3 additions & 0 deletions tools/backup-projects.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

# Pipestatus
set -o pipefail
umask 077 # Secure permissions for backups

# --- Configuration ---
CONFIG_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/dotfiles/config.yaml"
Expand Down Expand Up @@ -351,7 +352,9 @@ 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"
Expand Down
Loading