Back to skill

Security audit

Claude OAuth Auto-Renewal

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent token-renewal purpose, but it automates sensitive Claude account authorization through Keychain and Chrome with weak consent boundaries and unsafe scripting details.

Install only if you are comfortable with an automated heartbeat process reading Claude Code Keychain credential data and driving Chrome to approve Claude OAuth. Prefer disabling Tier 2 browser automation unless strictly needed, use an isolated browser/profile if possible, avoid leaving Chrome Apple Events enabled broadly, and ask the publisher to add explicit runtime consent, safer temp-file handling, auth-code validation, and a non-dynamic Expect invocation before routine use.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/check-claude-oauth.sh:72
Finding

OAuth Callback Content Injection into Tcl/Expect Program

Content
View full analysis
{ const el = document.querySelector(\".font-mono, [class*=code], code, pre\"); return el ? el.textContent.trim() : \"no_element\"; })()" }); return code || "no_code"; } catch(e) { return "js_error:" + e.message; } } } } return "no_tab"; } ' 2>/dev/null || echo "osascript_error" } ``` ```bash auth_code="" for attempt in $(seq 1 10); do auth_code=$(extract_code_from_chrome) case "$auth_code" in no_tab|no_element|no_code|js_error:*|osascript_error) sleep 1 ;; *) break ;; esac done if [ -z "$auth_code" ] || [[ "$auth_code" == no_* ]] || [[ "$auth_code" == *error* ]]; then kill "$login_pid" 2>/dev/null || true return 1 fi # 5. Kill PTY process, feed code to fresh auth login via expect kill "$login_pid" 2>/dev/null || true sleep 1 expect -c " set timeout 30 spawn claude auth login expect { timeout { exit 1 } -re {visit:|browser} { sleep 6 } } send \"$auth_code\r\" expect { timeout { exit 1 } -re {successful|success|Login} { exit 0 } } " &>/tmp/claude-auth-expect.log ``` ### Technical Analysis The script extracts text from a browser page and int ...[truncated 2756 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/check-claude-oauth.sh:96
Finding

Predictable Authentication Log Files in Shared Temporary Directory

Content
View full analysis
/dev/null & local login_pid=$! ``` ```bash expect -c " set timeout 30 spawn claude auth login expect { timeout { exit 1 } -re {visit:|browser} { sleep 6 } } send \"$auth_code\r\" expect { timeout { exit 1 } -re {successful|success|Login} { exit 0 } } " &>/tmp/claude-auth-expect.log ``` ### Technical Analysis The authentication flow writes to two fixed paths in the globally shared `/tmp` directory: - `/tmp/claude-auth-pty.log` - `/tmp/claude-auth-expect.log` Neither path is securely created before use. The script does not use `mktemp`, verify file ownership, reject symbolic links, set a restrictive `umask`, or remove the files after completion. Predictable temporary paths create two related risks: 1. **Symbolic-link or file-clobber attacks:** A local attacker may pre-create one of the paths as a symbolic link. When the victim runs the heartbeat, `script` or the shell redirection may follow the link and overwrite a file writable by the victim. 2. **Authentication data retention:** PTY and Expect transcripts can contain login prompts, URLs, status output, and potentially echoed authorization material. Fixed log files remain after execution and may be readable by other local users depending on the process umask and file permissions. The exact disclosure or overwrite outcome depends on macOS temporary-directory behavior, ownership, permissions, the active umask, and whether the target utilities reject existing links. The implementation does not explicitly enforce the required ...[truncated 1598 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (12)

Credential Access

High
Category
Privilege Escalation
Confidence
80% confidence
Finding

The skill documentation explicitly describes the storage location, structure, and token prefixes for both access and refresh tokens. While not an exploit by itself, this materially lowers the barrier for credential harvesting by telling an operator or attacker exactly where high-value secrets reside and how to recognize them; in the context of an auto-renewal skill that handles OAuth tokens, that increases the danger.

Content

Scanner excerpt · SKILL.md (reported line 48)May include surrounding context.

md
Claude Code stores OAuth tokens in **macOS Keychain** under the service name `Claude Code-credentials`. The token JSON includes:

- `accessToken` — API access token (prefix `sk-ant-oat01-`)
- `refreshToken` — Used for automatic renewal (prefix `sk-ant-ort01-`)
- `expiresAt` — Unix timestamp in milliseconds

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 100)May include surrounding context.

md
### "无法读取 Claude Code token"
- Run `claude auth login` manually to establish initial credentials
- Verify keychain access: `security find-generic-password -s "Claude Code-credentials" -a "$(whoami)" -g`

### Tier 2 (browser automation) not working
- Enable Chrome JXA: `View → Developer → Allow JavaScript from Apple Events`

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 54)May include surrounding context.

md
# For OpenClaw heartbeat integration
#
# Flow:
#   1. Read token expiry from macOS Keychain
#   2. Healthy (>WARN_HOURS) → silent exit
#   3. Expiring/expired → claude auth status (refresh token)
#   4. Refresh fails → claude auth login + Chrome auto-Authorize + extract code + feed to CLI

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/check-claude-oauth.sh (reported line 6)May include surrounding context.

sh
# For OpenClaw heartbeat integration
#
# Flow:
#   1. Read token expiry from macOS Keychain
#   2. Healthy (>WARN_HOURS) → silent exit
#   3. Expiring/expired → claude auth status (refresh token)
#   4. Refresh fails → claude auth login + Chrome auto-Authorize + extract code + feed to CLI

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/check-claude-oauth.sh (reported line 12)May include surrounding context.

sh
# For OpenClaw heartbeat integration
#
# Flow:
#   1. Read token expiry from macOS Keychain
#   2. Healthy (>WARN_HOURS) → silent exit
#   3. Expiring/expired → claude auth status (refresh token)
#   4. Refresh fails → claude auth login + Chrome auto-Authorize + extract code + feed to CLI

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/check-claude-oauth.sh (reported line 21)May include surrounding context.

sh
set -euo pipefail

WARN_HOURS=${WARN_HOURS:-6}
KEYCHAIN_SERVICE="Claude Code-credentials"
KEYCHAIN_ACCOUNT="$(whoami)"
AUTH_TIMEOUT=30

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/check-claude-oauth.sh (reported line 22)May include surrounding context.

sh
set -euo pipefail

WARN_HOURS=${WARN_HOURS:-6}
KEYCHAIN_SERVICE="Claude Code-credentials"
KEYCHAIN_ACCOUNT="$(whoami)"
AUTH_TIMEOUT=30

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/check-claude-oauth.sh (reported line 28)May include surrounding context.

sh
set -euo pipefail

WARN_HOURS=${WARN_HOURS:-6}
KEYCHAIN_SERVICE="Claude Code-credentials"
KEYCHAIN_ACCOUNT="$(whoami)"
AUTH_TIMEOUT=30

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README explicitly documents a workflow that reads stored OAuth credentials from the macOS Keychain, automates browser authorization, extracts an authorization code from a callback page, and feeds it back into the CLI. Even though this is presented as operational automation, it handles highly sensitive authentication material and account actions without any prominent warning, consent boundary, or discussion of security risks, which makes accidental credential exposure or unauthorized account action significantly more likely.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
92% confidence
Finding

The instruction to enable Chrome's AppleScriptEnabled / 'Allow JavaScript from Apple Events' weakens browser security by permitting automation of web content from local scripts. In this skill's context, that expanded automation capability is especially sensitive because it is used to drive OAuth login and authorization flows, creating a path for local script abuse, session hijacking, or unintended consent actions if the host or agent environment is compromised.

Content

Scanner excerpt · SKILL.md (reported line 104)May include surrounding context.

md
### Tier 2 (browser automation) not working
- Enable Chrome JXA: `View → Developer → Allow JavaScript from Apple Events`
- Or via CLI: `defaults write com.google.Chrome AppleScriptEnabled -bool true` (restart Chrome)
- Ensure you're logged into claude.ai in Chrome

### JSON parsing errors

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script automates an OAuth authorization flow by controlling Chrome, clicking the Authorize button, extracting the authorization code from the callback page, and replaying it into claude auth login without explicit user consent at runtime. This bypasses the normal user-mediated trust boundary of OAuth and creates a powerful mechanism for silent account/session takeover if the script is triggered unexpectedly or modified to target other accounts or scopes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The get_expires_at function accesses the macOS Keychain to retrieve Claude credential data, which is a sensitive credential store access. While this is commented in the file header, there is no visible prompt, log message, or user warning when the script performs the access.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.