Back to skill

Security audit

Claude Connect

Security checks for vulnerabilities and agentic risk

Overview

This skill is not proven malicious, but it installs a persistent credential refresher for a deprecated use case and has serious token-handling weaknesses.

Do not install this unless you are intentionally maintaining a legacy Clawdbot setup and accept a persistent process that can read and update Claude OAuth credentials. Prefer Clawdbot's native onboarding path. If already installed, use uninstall.sh and verify launchctl no longer lists com.clawdbot.claude-oauth-refresher; also review claude-oauth-refresh-config.json, especially token_url, and treat the skill directory and config as credential-sensitive.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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
Findings (3)

T06 · System Persistence

Error
Location
install.sh:201
Finding
<![CDATA[Deprecated Skill Installs a Persistent Credential-Handling LaunchAgent]]><![CDATA[ ## Vulnerability Details **File Location**: `install.sh:201-240` **Vulnerability Type**: Persistent scheduled service exceeding current functional necessity **Risk Level**: High ### Vulnerable Code ```bash <key>StartInterval</key> <integer>7200</integer> <key>RunAtLoad</key> <true/> <key>StandardOutPath</key> <string>$HOME/clawd/logs/claude-oauth-refresher-stdout.log</string> <key>StandardErrorPath</key> <string>$HOME/clawd/logs/claude-oauth-refresher-stderr.log</string> <key>WorkingDirectory</key> <string>$SCRIPT_DIR</string> <key>EnvironmentVariables</key> <dict> <key>PATH</key> <string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$HOME/.local/bin</string> </dict> </dict> </plist> EOF echo -e "${GREEN}✓${NC} Created $PLIST_FILE" echo "" # Step 5: Install launchd plist echo -e "${BLUE}[5/6]${NC} Installing launchd service..." mkdir -p "$LAUNCHAGENTS_DIR" # Unload if already loaded if launchctl list | grep -q "com.clawdbot.claude-oauth-refresher"; then launchctl unload "$LAUNCHAGENTS_DIR/$PLIST_FILE" 2>/dev/null || true echo " → Unloaded existing service" fi cp "$SCRIPT_DIR/$PLIST_FILE" "$LAUNCHAGENTS_DIR/$PLIST_FILE" launchctl load "$LAUNCHAGENTS_DIR/$PLIST_FILE" ``` ### Technical Analysis The installer creates and loads a per-user macOS LaunchAgent with `RunAtLoad` enabled and a 7,200-second execution interval. This causes `refresh-token.sh` to survive the installation session and execute at login/load and every two hours. Automatic scheduling was historically related to the Skill's declared token-refresh purpose, and the persistence behavior is disclosed in `SKILL.md` and `QUICKSTART.md`. However, `README.md:1-10` explicitly states that the Skill is deprecated because Clawdbot now provides native token refresh. Installing an additional persistent process that repeatedly accesses OAuth credentials therefore exceeds the minimum privileges and ...[truncated 1896 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Disable or remove `install.sh` from the deprecated release and direct users to `clawdbot onboard --auth-choice claude-cli`. 2. Do not install a LaunchAgent by default. If legacy scheduling must remain available, require a separate, explicit opt-in after clearly explaining that it creates a persistent credential-handling service. 3. Install executable code into a user-owned directory with restrictive permissions and verify ownership and permissions before loading it. 4. Refuse to run if the script or configuration is writable by other users. 5. Use modern `launchctl bootstrap` and `bootout` commands with an explicit user GUI domain where supported. 6. Correct `README.md:27` to use the actual plist name: `com.clawdbot.claude-oauth-refresher.plist`. 7. Add an upgrade or migration routine that detects and removes legacy LaunchAgents after confirming with the user. 8. Document a complete removal check, including verification that `launchctl list` no longer contains the service label. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
refresh-token.sh:272
Finding
<![CDATA[Configurable OAuth Endpoint Can Receive the Keychain Refresh Token]]><![CDATA[ ## Vulnerability Details **File Location**: `refresh-token.sh:39-40, 64-65, 272-281` **Vulnerability Type**: Unvalidated destination for transmission of an OAuth refresh token **Risk Level**: High ### Vulnerable Code ```bash CLIENT_ID=$(jq -r '.client_id // ""' "$CONFIG_FILE") TOKEN_URL=$(jq -r '.token_url // ""' "$CONFIG_FILE") ``` ```bash CLIENT_ID="${CLIENT_ID:-$DEFAULT_CLIENT_ID}" TOKEN_URL="${TOKEN_URL:-$DEFAULT_TOKEN_URL}" ``` ```bash # Step 2: Call OAuth endpoint log "Calling OAuth endpoint..." RESPONSE=$(curl -s -X POST "$TOKEN_URL" \ -H "Content-Type: application/json" \ --max-time 30 \ -d "{ \"grant_type\": \"refresh_token\", \"refresh_token\": \"$REFRESH_TOKEN\", \"client_id\": \"$CLIENT_ID\" }") || error_exit "Network error calling OAuth endpoint" ``` The example configuration explicitly exposes this setting: ```json "_oauth_comment": "OAuth endpoint configuration", "client_id": "9d1c250a-e61b-44d9-88ed-5944d1962f5e", "token_url": "https://console.anthropic.com/v1/oauth/token" ``` ### Technical Analysis The refresh token is obtained from macOS Keychain and then transmitted to the URL supplied by `token_url` in the local JSON configuration. The script does not enforce HTTPS, validate the hostname, constrain the port or path, or require confirmation when the URL differs from Anthropic's endpoint. The repository's default destination is the legitimate Anthropic endpoint, so the code does not demonstrate intentional exfiltration by default. The vulnerability arises because a local configuration change can redirect a highly sensitive bearer credential to an arbitrary destination. This risk is amplified by the LaunchAgent, which processes the configuration automatically every two hours. The `curl` invocation also does not explicitly disable redirects. Depending on curl behavior and redirect status, redirects may introduce additional ambiguity around the final network destination. The comm ...[truncated 1436 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `token_url` and `client_id` from user-editable configuration unless custom OAuth providers are an essential supported feature. 2. Hard-code the expected endpoint as: `https://console.anthropic.com/v1/oauth/token`. 3. If configurability is essential, parse and validate the URL before use: - Require the `https` scheme. - Require an exact allowlisted hostname. - Require the expected port and path. - Reject embedded credentials, fragments, unexpected query parameters, and non-standard ports. 4. Disable redirects with `--max-redirs 0`, or independently validate every redirect destination before forwarding sensitive request data. 5. Use `curl --fail-with-body --show-error --silent` and verify the HTTP status and response content type. 6. Check configuration ownership and permissions before reading security-sensitive endpoint settings. 7. Require explicit interactive approval when a non-default endpoint is selected; scheduled execution should fail closed rather than approve a changed destination. 8. Avoid placing secrets directly in command-line arguments where practical. Submit a securely generated request body through standard input. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
refresh-token.sh:305
Finding
<![CDATA[Untrusted Values Are Interpolated into Executable Python Source]]><![CDATA[ ## Vulnerability Details **File Location**: `refresh-token.sh:305-350` **Vulnerability Type**: Python code injection through an unquoted shell heredoc **Risk Level**: High ### Vulnerable Code ```bash python3 << PYEOF import json import os import tempfile data = {'version': 1, 'profiles': {}} if os.path.exists('$AUTH_FILE'): try: with open('$AUTH_FILE') as f: content = f.read().strip() if content: data = json.loads(content) except (json.JSONDecodeError, Exception): pass if 'profiles' not in data: data['profiles'] = {} # FIXED: Write proper OAuth format with access/refresh/expires data['profiles']['$PROFILE_NAME'] = { 'type': 'oauth', 'provider': 'anthropic', 'access': '$NEW_ACCESS', 'refresh': '$NEW_REFRESH', 'expires': $NEW_EXPIRES_AT } # Set order to prefer OAuth profile if 'order' not in data: data['order'] = {} data['order']['anthropic'] = ['$PROFILE_NAME'] # Set lastGood if 'lastGood' not in data: data['lastGood'] = {} data['lastGood']['anthropic'] = '$PROFILE_NAME' # Atomic write auth_dir = os.path.dirname('$AUTH_FILE') fd, temp_path = tempfile.mkstemp(dir=auth_dir, suffix='.tmp') try: with os.fdopen(fd, 'w') as f: json.dump(data, f, indent=2) os.rename(temp_path, '$AUTH_FILE') except: os.unlink(temp_path) raise PYEOF ``` A similar vulnerable heredoc is used when synchronizing an existing Keychain token at `refresh-token.sh:210-256`, and another shell-expanded Python heredoc constructs Keychain JSON at `refresh-token.sh:363-375`. ### Technical Analysis The heredoc delimiter is unquoted, so the shell expands variables before Python parses the program. Values such as `AUTH_FILE`, `PROFILE_NAME`, `NEW_ACCESS`, and `NEW_REFRESH` are inserted directly between Python string delimiters without any Python escaping. These values originate from configuration files, Keychain data, or the OAuth endpoint response. A value containi ...[truncated 2403 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not interpolate shell variables into Python source code. 2. Replace the generated program with fixed Python code and pass all values as data through: - Environment variables; - Command-line arguments with careful length and visibility considerations; or - Preferably, a JSON document supplied over standard input. 3. In Python, parse the input with `json.load()` and assign the resulting values directly to dictionaries. 4. Validate OAuth response types before use: - Require tokens to be strings. - Enforce reasonable length limits. - Require `expires_in` to be a bounded positive integer. 5. Validate configuration fields such as `profile_name` against a restrictive allowlist. 6. Keep file paths as data and verify that the resolved authentication path is within the intended Clawdbot directory. 7. Apply restrictive permissions to generated authentication files and temporary files, such as mode `0600`. 8. Quote heredoc delimiters where shell expansion is unnecessary. Quoting alone is not sufficient when values still need to be passed; values must be transmitted through a data channel. 9. Add tests using tokens and configuration values containing quotes, backslashes, newlines, and code-like text to verify that they remain inert data. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (166)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
You can safely:
1. Remove the launchd job: `launchctl unload ~/Library/LaunchAgents/com.clawdbot.claude-oauth-refresh.plist`
2. Delete the skill folder: `rm -rf ~/clawd/skills/claude-connect`
3. Remove any related cron jobs

Your tokens will continue to work via Clawdbot's native support.
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
You can safely:
1. Remove the launchd job: `launchctl unload ~/Library/LaunchAgents/com.clawdbot.claude-oauth-refresh.plist`
2. Delete the skill folder: `rm -rf ~/clawd/skills/claude-connect`
3. Remove any related cron jobs

Your tokens will continue to work via Clawdbot's native support.
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
You can safely:
1. Remove the launchd job: `launchctl unload ~/Library/LaunchAgents/com.clawdbot.claude-oauth-refresh.plist`
2. Delete the skill folder: `rm -rf ~/clawd/skills/claude-connect`
3. Remove any related cron jobs

Your tokens will continue to work via Clawdbot's native support.
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
You can safely:
1. Remove the launchd job: `launchctl unload ~/Library/LaunchAgents/com.clawdbot.claude-oauth-refresh.plist`
2. Delete the skill folder: `rm -rf ~/clawd/skills/claude-connect`
3. Remove any related cron jobs

Your tokens will continue to work via Clawdbot's native support.
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
You can safely:
1. Remove the launchd job: `launchctl unload ~/Library/LaunchAgents/com.clawdbot.claude-oauth-refresh.plist`
2. Delete the skill folder: `rm -rf ~/clawd/skills/claude-connect`
3. Remove any related cron jobs

Your tokens will continue to work via Clawdbot's native support.
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared purpose understates sensitive behaviors such as Keychain access, OAuth calls, credential store modification, gateway restart, and outbound notifications. Users may consent to a simple connector without realizing it handles secrets and persistence, increasing the chance of unsafe installation.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The declared purpose understates sensitive behaviors such as Keychain access, OAuth calls, credential store modification, gateway restart, and outbound notifications. Users may consent to a simple connector without realizing it handles secrets and persistence, increasing the chance of unsafe installation.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared purpose understates sensitive behaviors such as Keychain access, OAuth calls, credential store modification, gateway restart, and outbound notifications. Users may consent to a simple connector without realizing it handles secrets and persistence, increasing the chance of unsafe installation.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared purpose understates sensitive behaviors such as Keychain access, OAuth calls, credential store modification, gateway restart, and outbound notifications. Users may consent to a simple connector without realizing it handles secrets and persistence, increasing the chance of unsafe installation.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared purpose understates sensitive behaviors such as Keychain access, OAuth calls, credential store modification, gateway restart, and outbound notifications. Users may consent to a simple connector without realizing it handles secrets and persistence, increasing the chance of unsafe installation.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared purpose understates sensitive behaviors such as Keychain access, OAuth calls, credential store modification, gateway restart, and outbound notifications. Users may consent to a simple connector without realizing it handles secrets and persistence, increasing the chance of unsafe installation.

Credential Access

High
Category
Privilege Escalation
Content
### Refresh Process

1. **Read from Keychain:** Gets OAuth tokens from `Claude Code-credentials`
2. **Check Expiry:** Only refreshes if < 30 minutes left (or `--force`)
3. **Call OAuth API:** Gets new access + refresh tokens
4. **Update auth-profiles.json:** Writes proper OAuth format
Confidence
97% confidence
Finding
The skill is designed to read OAuth credentials from macOS Keychain, which is highly sensitive secret material. Any automation that extracts and repurposes those tokens broadens the trust boundary and can enable account compromise if logs, files, or downstream components are exposed.

Credential Access

High
Category
Privilege Escalation
Content
2. **Check Expiry:** Only refreshes if < 30 minutes left (or `--force`)
3. **Call OAuth API:** Gets new access + refresh tokens
4. **Update auth-profiles.json:** Writes proper OAuth format
5. **Update Keychain:** Syncs new tokens back
6. **Restart Gateway:** Picks up new tokens
7. **Notify:** Sends success/failure message (optional)
Confidence
97% confidence
Finding
Updating Keychain with refreshed tokens means the skill both reads and writes live credentials, increasing the chance of credential corruption, interception, or unintended persistence. Combined with auth-profile writing and notifications, this creates a concentrated secret-management component with substantial blast radius.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```bash
# Stop auto-refresh
launchctl unload ~/Library/LaunchAgents/com.clawdbot.claude-oauth-refresher.plist
rm ~/Library/LaunchAgents/com.clawdbot.claude-oauth-refresher.plist

# Remove skill
rm -rf ~/clawd/skills/claude-connect
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Credential Access

High
Category
Privilege Escalation
Content
- Calculates expiry with buffer (default: 30 min)
- Makes OAuth request to `auth.anthropic.com`
- Updates `auth-profiles.json` atomically
- Updates Keychain if refresh token rotates
- Sends notifications via Clawdbot
- Comprehensive error handling with actionable messages
Confidence
93% confidence
Finding
The skill is explicitly designed to access, use, and rotate OAuth refresh tokens from macOS Keychain, then update local auth state and contact an external OAuth endpoint. In this context, credential access is intentional, but it is still security-sensitive because a compromised or modified script would have persistent access to long-lived tokens and could silently abuse them.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
# We show:
✗ No refresh token found
  → No refresh token in Keychain
  → Run: claude auth
```
Confidence
80% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Credential Access

High
Category
Privilege Escalation
Content
"refresh_buffer_minutes": 30,
  "log_file": "~/clawd/logs/claude-oauth-refresh.log",
  
  "_keychain_comment": "Keychain settings - where tokens are stored (account auto-discovered)",
  "keychain_service": "Claude Code-credentials",
  "keychain_field": "claudeAiOauth",
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"refresh_buffer_minutes": 30,
  "log_file": "~/clawd/logs/claude-oauth-refresh.log",
  
  "_keychain_comment": "Keychain settings - where tokens are stored (account auto-discovered)",
  "keychain_service": "Claude Code-credentials",
  "keychain_field": "claudeAiOauth",
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"refresh_buffer_minutes": 30,
  "log_file": "~/clawd/logs/claude-oauth-refresh.log",
  
  "_keychain_comment": "Keychain settings - where tokens are stored (account auto-discovered)",
  "keychain_service": "Claude Code-credentials",
  "keychain_field": "claudeAiOauth",
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"refresh_buffer_minutes": 30,
  "log_file": "~/clawd/logs/claude-oauth-refresh.log",
  
  "_keychain_comment": "Keychain settings - where tokens are stored (account auto-discovered)",
  "keychain_service": "Claude Code-credentials",
  "keychain_field": "claudeAiOauth",
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"refresh_buffer_minutes": 30,
  "log_file": "~/clawd/logs/claude-oauth-refresh.log",
  
  "_keychain_comment": "Keychain settings - where tokens are stored (account auto-discovered)",
  "keychain_service": "Claude Code-credentials",
  "keychain_field": "claudeAiOauth",
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"refresh_buffer_minutes": 30,
  "log_file": "~/clawd/logs/claude-oauth-refresh.log",
  
  "_keychain_comment": "Keychain settings - where tokens are stored (account auto-discovered)",
  "keychain_service": "Claude Code-credentials",
  "keychain_field": "claudeAiOauth",
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"refresh_buffer_minutes": 30,
  "log_file": "~/clawd/logs/claude-oauth-refresh.log",
  
  "_keychain_comment": "Keychain settings - where tokens are stored (account auto-discovered)",
  "keychain_service": "Claude Code-credentials",
  "keychain_field": "claudeAiOauth",
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"refresh_buffer_minutes": 30,
  "log_file": "~/clawd/logs/claude-oauth-refresh.log",
  
  "_keychain_comment": "Keychain settings - where tokens are stored (account auto-discovered)",
  "keychain_service": "Claude Code-credentials",
  "keychain_field": "claudeAiOauth",
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"refresh_buffer_minutes": 30,
  "log_file": "~/clawd/logs/claude-oauth-refresh.log",
  
  "_keychain_comment": "Keychain settings - where tokens are stored (account auto-discovered)",
  "keychain_service": "Claude Code-credentials",
  "keychain_field": "claudeAiOauth",
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Static analysis

No suspicious patterns detected.