-
Notifications
You must be signed in to change notification settings - Fork 1
🛡️ Sentinel: [MEDIUM] Secure backup file permissions #36
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,4 @@ | ||
| ## 2024-05-24 - Secure Backup Permissions | ||
|
Check failure on line 1 in .jules/sentinel.md
|
||
| **Vulnerability:** Backup archives created by `zip` without explicit permissions were world-readable (depending on umask), exposing sensitive project data. | ||
|
Check failure on line 2 in .jules/sentinel.md
|
||
| **Learning:** `mkdir -p` and `zip` respect the process `umask`, but relying on system defaults is insecure for sensitive data. | ||
|
Check failure on line 3 in .jules/sentinel.md
|
||
| **Prevention:** Explicitly set `umask 077` at the start of sensitive operations and use `chmod` to enforce restrictive permissions (600/700) on critical artifacts. | ||
|
Check failure on line 4 in .jules/sentinel.md
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -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" <<EOF | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| backup: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| folders: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| - $TEST_SOURCE | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| local: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| base_dir: $TEST_BACKUP_DIR | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| retention_days: 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| remote: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| enabled: false | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| logging: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| enabled: false | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| EOF | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+19
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test isolation broken: backup script writes The test config sets Add 🐛 Proposed fix cat > "$TEST_CONFIG" <<EOF
backup:
folders:
- $TEST_SOURCE
local:
base_dir: $TEST_BACKUP_DIR
retention_days: 1
remote:
enabled: false
logging:
enabled: false
+ dir: $TEST_DIR/state
EOF📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Make sure script is executable | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| chmod +x "$SCRIPT_PATH" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Run backup script | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| "$SCRIPT_PATH" backup --config "$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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -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" | ||||||||||||||||
|
Comment on lines
+431
to
+432
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The script sets 🛡️ Proposed fix- # Ensure secure permissions for backup archive (600)
- chmod 600 "$archive_path"
+ # Ensure secure permissions for backup archive (600)
+ if ! chmod 600 "$archive_path"; then
+ error "Failed to set secure permissions on archive: $archive_path"
+ return 1
+ fi📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||
|
|
||||||||||||||||
| local archive_size | ||||||||||||||||
| archive_size=$(du -h "$archive_path" | cut -f1) | ||||||||||||||||
| say "Archive created: $archive_size" | ||||||||||||||||
|
|
||||||||||||||||
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.
Fix 5
markdownlintviolations failing CI.The
Lint Documentationcheck is failing with five violations:#(H1), not##(H2)📝 Proposed fix
📝 Committable suggestion
🧰 Tools
🪛 GitHub Check: Lint Documentation
[failure] 4-4: Line length
.jules/sentinel.md:4:81 MD013/line-length Line length [Expected: 80; Actual: 163] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md
[failure] 3-3: Line length
.jules/sentinel.md:3:81 MD013/line-length Line length [Expected: 80; Actual: 126] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md
[failure] 2-2: Line length
.jules/sentinel.md:2:81 MD013/line-length Line length [Expected: 80; Actual: 155] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md013.md
[failure] 1-1: First line in a file should be a top-level heading
.jules/sentinel.md:1 MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "## 2024-05-24 - Secure Backup ..."] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md041.md
[failure] 1-1: Headings should be surrounded by blank lines
.jules/sentinel.md:1 MD022/blanks-around-headings Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "## 2024-05-24 - Secure Backup Permissions"] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md022.md
🤖 Prompt for AI Agents