diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000..90186a1 --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2025-02-08 - TOCTOU Race Condition in File Creation +**Vulnerability:** The SSH private key was being created with default permissions (potentially world-readable) before `chmod 600` was applied. This created a race condition where the key could be read by other users on the system. +**Learning:** Shell redirection (`>`) creates files with the current `umask` before any subsequent `chmod` command is executed. +**Prevention:** Use `umask 077` in a subshell when creating sensitive files to ensure they are created with restricted permissions from the start. Example: `(umask 077; command > file)`. diff --git a/tools/setup-ssh-keys.sh b/tools/setup-ssh-keys.sh index bde52fd..4ecc6d9 100755 --- a/tools/setup-ssh-keys.sh +++ b/tools/setup-ssh-keys.sh @@ -148,12 +148,17 @@ cmd_restore() { say "Restoring SSH key from 1Password..." - # Create SSH directory - mkdir -p "$SSH_DIR" + # Create SSH directory with secure permissions + if [[ ! -d "$SSH_DIR" ]]; then + mkdir -p -m 700 "$SSH_DIR" + fi chmod 700 "$SSH_DIR" - # Read private key from 1Password and save locally - op read "op://$VAULT/$KEY_NAME/private_key" > "$PRIVATE_KEY_FILE" + # Read private key from 1Password and save locally with secure permissions + ( + umask 077 + op read "op://$VAULT/$KEY_NAME/private_key" > "$PRIVATE_KEY_FILE" + ) chmod 600 "$PRIVATE_KEY_FILE" # Read public key from 1Password and save locally