fix(security): prevent race condition in GitHub token file permissions (#3035)

Before this change, gh auth login wrote the token file with default
permissions, and chmod 600 was applied afterward — leaving a window
where the file could be read by other users on multi-user systems.

Now the credential directory is created with 700 permissions and umask
is set to 077 before the write, so the token file is created with
restrictive permissions from the start.

Agent: complexity-hunter
Fixes #3030

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
A 2026-03-26 16:59:42 -07:00 committed by GitHub
parent 0eed96f381
commit 7080d80472
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -308,6 +308,13 @@ ensure_gh_auth() {
fi
log_info "Persisting GITHUB_TOKEN to gh credential store..."
# Ensure credential directory exists with restrictive permissions BEFORE writing token
# (prevents race condition where token file is world-readable before chmod)
mkdir -p "${HOME}/.config/gh"
chmod 700 "${HOME}/.config/gh" 2>/dev/null || printf 'Warning: could not set restrictive permissions on gh config directory\n' >&2
# Set restrictive umask so the token file is created with 0600 permissions
_old_umask=$(umask)
umask 077
# GITHUB_TOKEN is already unset above so gh auth login won't refuse
# with "The value of the GITHUB_TOKEN environment variable is being
# used for authentication."
@ -315,14 +322,13 @@ ensure_gh_auth() {
${_gh_token}
EOF
log_error "Failed to authenticate with GITHUB_TOKEN"
umask "${_old_umask}"
export GITHUB_TOKEN="${_gh_token}"
return 1
}
# Restrict token file permissions to owner-only (prevents exposure on multi-user systems)
chmod 600 "${HOME}/.config/gh/hosts.yml" || {
log_error "Failed to restrict token file permissions — aborting to prevent credential exposure"
return 1
}
umask "${_old_umask}"
# Belt-and-suspenders: explicitly restrict token file permissions
chmod 600 "${HOME}/.config/gh/hosts.yml" 2>/dev/null || printf 'Warning: could not set restrictive permissions on gh credentials file\n' >&2
export GITHUB_TOKEN="${_gh_token}"
elif gh auth status &>/dev/null; then
log_info "Authenticated with GitHub CLI"