-
Notifications
You must be signed in to change notification settings - Fork 1
🛡️ Sentinel: [CRITICAL] Fix SSH key creation TOCTOU vulnerability #26
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-02-10 - [SSH Key Creation Race Condition] | ||
|
Check failure on line 1 in .jules/sentinel.md
|
||
| **Vulnerability:** SSH private keys were briefly world-readable during creation because `umask` was not restricted. The `op read ... > file` command created the file with default permissions (often 644/664), and `chmod 600` was only applied afterward. | ||
|
Check failure on line 2 in .jules/sentinel.md
|
||
| **Learning:** Shell redirection creates files before `chmod` runs. This creates a Time-of-Check to Time-of-Use (TOCTOU) window where sensitive data is exposed. | ||
|
Check failure on line 3 in .jules/sentinel.md
|
||
| **Prevention:** Always wrap sensitive file creation commands in a subshell with restricted umask: `(umask 077; command > sensitive_file)`. This ensures the file is born secure. | ||
|
Check failure on line 4 in .jules/sentinel.md
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| #!/bin/bash | ||
| set -e | ||
|
|
||
| # Setup test environment | ||
| TEST_DIR=$(mktemp -d) | ||
|
Comment on lines
+1
to
+5
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. Add a With Proposed fix #!/bin/bash
set -e
# Setup test environment
TEST_DIR=$(mktemp -d)
+trap 'rm -rf "$TEST_DIR"' EXIT
export HOME="$TEST_DIR"And remove the manual cleanup at the end: -# Cleanup
-rm -rf "$TEST_DIR"Also applies to: 84-85 🤖 Prompt for AI Agents |
||
| export HOME="$TEST_DIR" | ||
| export XDG_CONFIG_HOME="$TEST_DIR/.config" | ||
| export XDG_DATA_HOME="$TEST_DIR/.local/share" | ||
| mkdir -p "$TEST_DIR/.config/dotfiles" | ||
| mkdir -p "$TEST_DIR/.local/bin" | ||
|
|
||
| # Add mock bin to PATH | ||
| export PATH="$TEST_DIR/.local/bin:$PATH" | ||
|
|
||
| # Create mock op | ||
| cat <<EOF > "$TEST_DIR/.local/bin/op" | ||
| #!/bin/bash | ||
| if [[ "\$1" == "account" && "\$2" == "list" ]]; then | ||
| exit 0 | ||
| elif [[ "\$1" == "item" && "\$2" == "get" ]]; then | ||
| exit 0 | ||
| elif [[ "\$1" == "read" ]]; then | ||
| if [[ "\$2" == *"private_key"* ]]; then | ||
| echo "MOCK_PRIVATE_KEY_CONTENT" | ||
| else | ||
| echo "MOCK_PUBLIC_KEY_CONTENT" | ||
| fi | ||
| else | ||
| exit 0 | ||
| fi | ||
| EOF | ||
| chmod +x "$TEST_DIR/.local/bin/op" | ||
|
|
||
| # Create mock yq (script uses it if available) | ||
| cat <<EOF > "$TEST_DIR/.local/bin/yq" | ||
| #!/bin/bash | ||
| echo "" # Return empty or default | ||
| EOF | ||
| chmod +x "$TEST_DIR/.local/bin/yq" | ||
|
|
||
| echo "Running setup-ssh-keys.sh restore in test environment..." | ||
|
|
||
| # Determine absolute path to the tool | ||
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| REPO_ROOT="$(dirname "$SCRIPT_DIR")" | ||
| TOOL_PATH="$REPO_ROOT/tools/setup-ssh-keys.sh" | ||
|
|
||
| # Run the tool | ||
| # Pass --vault and --name to avoid yq dependency issues or defaults | ||
| bash "$TOOL_PATH" restore --vault "testvault" --name "testkey" | ||
|
|
||
| # Verify permissions | ||
| PRIVATE_KEY="$HOME/.ssh/id_ed25519" | ||
|
|
||
| if [[ ! -f "$PRIVATE_KEY" ]]; then | ||
| echo "ERROR: Private key not created at $PRIVATE_KEY" | ||
| ls -la "$HOME/.ssh" | ||
| exit 1 | ||
| fi | ||
|
|
||
| PERMS=$(stat -c "%a" "$PRIVATE_KEY" 2>/dev/null || stat -f "%Lp" "$PRIVATE_KEY") | ||
|
|
||
| echo "Permissions of private key: $PERMS" | ||
|
|
||
| if [[ "$PERMS" != "600" ]]; then | ||
| echo "ERROR: Permissions are not 600!" | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "SUCCESS: Key created with correct permissions." | ||
|
|
||
| # Verify directory permissions | ||
| SSH_DIR="$HOME/.ssh" | ||
| DIR_PERMS=$(stat -c "%a" "$SSH_DIR" 2>/dev/null || stat -f "%Lp" "$SSH_DIR") | ||
| echo "Permissions of .ssh directory: $DIR_PERMS" | ||
|
|
||
| if [[ "$DIR_PERMS" != "700" ]]; then | ||
| echo "ERROR: Directory permissions are not 700!" | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "SUCCESS: Directory created with correct permissions." | ||
|
|
||
| # Cleanup | ||
| rm -rf "$TEST_DIR" | ||
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 markdown lint failures flagged by CI and correct the year.
2024-02-10— should be2026-02-10.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: 176] 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: 159] 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: 251] 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-02-10 - [SSH Key Creat..."] 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-02-10 - [SSH Key Creation Race Condition]"] https://github.com/DavidAnson/markdownlint/blob/v0.34.0/doc/md022.md
🤖 Prompt for AI Agents