-
Notifications
You must be signed in to change notification settings - Fork 81
Security Focused Updates - Thresher.sh findings #162
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
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 |
|---|---|---|
|
|
@@ -96,23 +96,31 @@ _init_bash() { | |
|
|
||
| __FUNC___run_post_cd_hooks() { | ||
| local dir="$1" | ||
| local _gtr_trust_dir="${XDG_CONFIG_HOME:-$HOME/.config}/gtr/trusted" | ||
|
|
||
| cd "$dir" && { | ||
| local _gtr_hooks _gtr_hook _gtr_seen _gtr_config_file | ||
| _gtr_hooks="" | ||
| _gtr_seen="" | ||
| # Read from git config (local > global > system) | ||
| _gtr_hooks="$(git config --get-all gtr.hook.postCd 2>/dev/null)" || true | ||
| # Read from .gtrconfig if it exists | ||
| # Read from .gtrconfig if it exists — only if trusted | ||
| _gtr_config_file="$(git rev-parse --show-toplevel 2>/dev/null)/.gtrconfig" | ||
| if [ -f "$_gtr_config_file" ]; then | ||
| local _gtr_file_hooks | ||
| _gtr_file_hooks="$(git config -f "$_gtr_config_file" --get-all hooks.postCd 2>/dev/null)" || true | ||
| if [ -n "$_gtr_file_hooks" ]; then | ||
| if [ -n "$_gtr_hooks" ]; then | ||
| _gtr_hooks="$_gtr_hooks"$'\n'"$_gtr_file_hooks" | ||
| # Verify trust before including .gtrconfig hooks | ||
| local _gtr_hook_hash | ||
| _gtr_hook_hash="$(git config -f "$_gtr_config_file" --get-regexp '^hooks\.' 2>/dev/null | shasum -a 256 | cut -d' ' -f1)" || true | ||
| if [ -n "$_gtr_hook_hash" ] && [ -f "$_gtr_trust_dir/$_gtr_hook_hash" ]; then | ||
| if [ -n "$_gtr_hooks" ]; then | ||
| _gtr_hooks="$_gtr_hooks"$'\n'"$_gtr_file_hooks" | ||
| else | ||
| _gtr_hooks="$_gtr_file_hooks" | ||
| fi | ||
| else | ||
| _gtr_hooks="$_gtr_file_hooks" | ||
| echo "__FUNC__: Untrusted .gtrconfig hooks skipped — run 'git gtr trust' to approve" >&2 | ||
|
Comment on lines
97
to
+123
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. These new shell-integration bodies are still hidden behind the old init cache.
Also applies to: 281-309, 468-492 🤖 Prompt for AI Agents
Comment on lines
+107
to
+123
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 post- Inside a linked worktree, Also applies to: 292-308, 480-492 🤖 Prompt for AI Agents |
||
| fi | ||
| fi | ||
| fi | ||
|
|
@@ -273,23 +281,31 @@ _init_zsh() { | |
| __FUNC___run_post_cd_hooks() { | ||
| emulate -L zsh | ||
| local dir="$1" | ||
| local _gtr_trust_dir="${XDG_CONFIG_HOME:-$HOME/.config}/gtr/trusted" | ||
|
|
||
| cd "$dir" && { | ||
| local _gtr_hooks _gtr_hook _gtr_seen _gtr_config_file | ||
| _gtr_hooks="" | ||
| _gtr_seen="" | ||
| # Read from git config (local > global > system) | ||
| _gtr_hooks="$(git config --get-all gtr.hook.postCd 2>/dev/null)" || true | ||
| # Read from .gtrconfig if it exists | ||
| # Read from .gtrconfig if it exists — only if trusted | ||
| _gtr_config_file="$(git rev-parse --show-toplevel 2>/dev/null)/.gtrconfig" | ||
| if [ -f "$_gtr_config_file" ]; then | ||
| local _gtr_file_hooks | ||
| _gtr_file_hooks="$(git config -f "$_gtr_config_file" --get-all hooks.postCd 2>/dev/null)" || true | ||
| if [ -n "$_gtr_file_hooks" ]; then | ||
| if [ -n "$_gtr_hooks" ]; then | ||
| _gtr_hooks="$_gtr_hooks"$'\n'"$_gtr_file_hooks" | ||
| # Verify trust before including .gtrconfig hooks | ||
| local _gtr_hook_hash | ||
| _gtr_hook_hash="$(git config -f "$_gtr_config_file" --get-regexp '^hooks\.' 2>/dev/null | shasum -a 256 | cut -d' ' -f1)" || true | ||
| if [ -n "$_gtr_hook_hash" ] && [ -f "$_gtr_trust_dir/$_gtr_hook_hash" ]; then | ||
| if [ -n "$_gtr_hooks" ]; then | ||
| _gtr_hooks="$_gtr_hooks"$'\n'"$_gtr_file_hooks" | ||
| else | ||
| _gtr_hooks="$_gtr_file_hooks" | ||
| fi | ||
| else | ||
| _gtr_hooks="$_gtr_file_hooks" | ||
| echo "__FUNC__: Untrusted .gtrconfig hooks skipped — run 'git gtr trust' to approve" >&2 | ||
| fi | ||
| fi | ||
| fi | ||
|
|
@@ -451,17 +467,30 @@ _init_fish() { | |
|
|
||
| function __FUNC___run_post_cd_hooks | ||
| set -l dir "$argv[1]" | ||
| set -l _gtr_trust_dir "$HOME/.config/gtr/trusted" | ||
| if set -q XDG_CONFIG_HOME | ||
| set _gtr_trust_dir "$XDG_CONFIG_HOME/gtr/trusted" | ||
| end | ||
| cd $dir | ||
| and begin | ||
| set -l _gtr_hooks | ||
| set -l _gtr_seen | ||
| # Read from git config (local > global > system) | ||
| set -l _gtr_git_hooks (git config --get-all gtr.hook.postCd 2>/dev/null) | ||
| # Read from .gtrconfig if it exists | ||
| # Read from .gtrconfig if it exists — only if trusted | ||
| set -l _gtr_config_file (git rev-parse --show-toplevel 2>/dev/null)"/.gtrconfig" | ||
| set -l _gtr_file_hooks | ||
| if test -f "$_gtr_config_file" | ||
| set _gtr_file_hooks (git config -f "$_gtr_config_file" --get-all hooks.postCd 2>/dev/null) | ||
| set -l _gtr_candidate_hooks (git config -f "$_gtr_config_file" --get-all hooks.postCd 2>/dev/null) | ||
| if test (count $_gtr_candidate_hooks) -gt 0 | ||
| # Verify trust before including .gtrconfig hooks | ||
| set -l _gtr_hook_hash (git config -f "$_gtr_config_file" --get-regexp '^hooks\.' 2>/dev/null | shasum -a 256 | cut -d' ' -f1) | ||
| if test -n "$_gtr_hook_hash"; and test -f "$_gtr_trust_dir/$_gtr_hook_hash" | ||
| set _gtr_file_hooks $_gtr_candidate_hooks | ||
| else | ||
| echo "__FUNC__: Untrusted .gtrconfig hooks skipped — run 'git gtr trust' to approve" >&2 | ||
| end | ||
| end | ||
| end | ||
| # Merge and deduplicate | ||
| set _gtr_hooks $_gtr_git_hooks $_gtr_file_hooks | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,41 @@ | ||||||||||||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||||||||||||
| # Trust management for .gtrconfig hooks | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| cmd_trust() { | ||||||||||||||||||||||||
| local config_file | ||||||||||||||||||||||||
| config_file=$(_gtrconfig_path) | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| if [ -z "$config_file" ] || [ ! -f "$config_file" ]; then | ||||||||||||||||||||||||
| log_info "No .gtrconfig file found in this repository" | ||||||||||||||||||||||||
| return 0 | ||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| # Show all hook entries from .gtrconfig | ||||||||||||||||||||||||
| local hook_content | ||||||||||||||||||||||||
| hook_content=$(git config -f "$config_file" --get-regexp '^hooks\.' 2>/dev/null) || true | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| if [ -z "$hook_content" ]; then | ||||||||||||||||||||||||
| log_info "No hooks defined in $config_file" | ||||||||||||||||||||||||
| return 0 | ||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| if _hooks_are_trusted "$config_file"; then | ||||||||||||||||||||||||
| log_info "Hooks in $config_file are already trusted" | ||||||||||||||||||||||||
| log_info "Current hooks:" | ||||||||||||||||||||||||
| printf '%s\n' "$hook_content" >&2 | ||||||||||||||||||||||||
| return 0 | ||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| log_warn "The following hooks are defined in $config_file:" | ||||||||||||||||||||||||
| echo "" >&2 | ||||||||||||||||||||||||
| printf '%s\n' "$hook_content" >&2 | ||||||||||||||||||||||||
| echo "" >&2 | ||||||||||||||||||||||||
| log_warn "These commands will execute on your machine during gtr operations." | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| if prompt_yes_no "Trust these hooks?"; then | ||||||||||||||||||||||||
| _hooks_mark_trusted "$config_file" | ||||||||||||||||||||||||
| log_info "Hooks marked as trusted" | ||||||||||||||||||||||||
|
Comment on lines
+35
to
+37
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. Don't report trust success when persistence failed.
♻️ Proposed fix if prompt_yes_no "Trust these hooks?"; then
- _hooks_mark_trusted "$config_file"
- log_info "Hooks marked as trusted"
+ if _hooks_mark_trusted "$config_file"; then
+ log_info "Hooks marked as trusted"
+ else
+ log_error "Failed to persist hook trust state"
+ return 1
+ fi
else📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
| else | ||||||||||||||||||||||||
| log_info "Hooks remain untrusted and will not execute" | ||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
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.
Validate only the adapter selector, not the full generic command.
This check runs before generic fallback and rejects any
/anywhere inname. That blocks legitimate commands likebunx@github/copilot@latest—the same form called out in the new example on Line 183—even though the executable being resolved is justbunx.♻️ Proposed fix
_load_adapter() { - local type="$1" name="$2" label="$3" builtin_list="$4" path_hint="$5" + local type="$1" name="$2" label="$3" builtin_list="$4" path_hint="$5" + local adapter_selector="${name%% *}" # Reject adapter names containing path traversal characters - case "$name" in + case "$adapter_selector" in */* | *..* | *\\*) log_error "$label name '$name' contains invalid characters" return 1 ;; esac🤖 Prompt for AI Agents