-
Notifications
You must be signed in to change notification settings - Fork 1
π‘οΈ Sentinel: [MEDIUM] Fix insecure backup permissions #35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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
|
||
| **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
|
||
| **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
|
||
| **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
|
||
| 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Markdown violations are failing CI β fix before merge.
The
Lint Documentationcheck reports two classes of failures:##heading (line 3)π Proposed fix
π Committable suggestion
π§° 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