From 5dd4a31467dd1ade5da4bc7b33d7f635b53624c4 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 04:35:17 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[CRITICAL]?= =?UTF-8?q?=20Fix=20race=20condition=20in=20SSH=20key=20creation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes a security race condition (CWE-362) where SSH private keys and directories were briefly created with default umask permissions (often world or group readable) before `chmod` was applied. Used `umask 077` in a subshell to ensure strict permissions at creation time. Co-authored-by: kidchenko <5432753+kidchenko@users.noreply.github.com> --- .jules/sentinel.md | 4 ++++ tools/setup-ssh-keys.sh | 9 +++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 .jules/sentinel.md diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000..272e219 --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2025-02-02 - Secure File Creation with Shell Redirection +**Vulnerability:** SSH private keys restored from 1Password via `op read > file` were created with default umask permissions before `chmod` was applied, creating a race condition. +**Learning:** Shell redirection creates files before `chmod` can act. Even in "personal" dotfiles, this can expose secrets on multi-user systems (e.g., shared servers). +**Prevention:** Use `(umask 077 && command > file)` to ensure files are born secure. diff --git a/tools/setup-ssh-keys.sh b/tools/setup-ssh-keys.sh index bde52fd..0286575 100755 --- a/tools/setup-ssh-keys.sh +++ b/tools/setup-ssh-keys.sh @@ -149,11 +149,16 @@ cmd_restore() { say "Restoring SSH key from 1Password..." # Create SSH directory - mkdir -p "$SSH_DIR" + # Use umask to ensure secure permissions on creation + (umask 077 && mkdir -p "$SSH_DIR") chmod 700 "$SSH_DIR" # Read private key from 1Password and save locally - op read "op://$VAULT/$KEY_NAME/private_key" > "$PRIVATE_KEY_FILE" + # Use umask in subshell to prevent race condition where file is briefly group-readable + ( + 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