Back to skill

Security audit

Claude Buddy Card

Security checks for vulnerabilities and agentic risk

Overview

This skill's card-generation goal is understandable, but it asks the agent to handle login tokens and API keys in ways users should review before installing.

Review carefully before installing. This skill should only be used if you are comfortable letting an agent read Claude Code credentials from Keychain, use the OAuth token to call Anthropic's profile endpoint, send generated prompts to Google/Gemini with your API key, and write a card image to disk. Use a restricted throwaway Google API key, avoid custom `GOOGLE_BASE_URL` or untrusted proxy settings, and prefer an already installed trusted runtime instead of the `npx -y bun` fallback.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate-image.ts:12
Finding

Google API Credential Can Be Redirected to an Arbitrary Server

Content
View full analysis
{ const res = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", "x-goog-api-key": API_KEY! }, body, }); if (!res.ok) throw new Error(`Google API error (${res.status}): ${await res.text()}`); return extractImage(await res.text()); } function generateViaCurl(): Uint8Array { const proxy = process.env.HTTPS_PROXY || process.env.HTTP_PROXY || process.env.https_proxy || process.env.http_proxy || null; const curlArgs = [ "-s", "--connect-timeout", "30", "--max-time", "300", ...(proxy ? ["-x", proxy] : []), url, "-H", "Content-Type: application/json", "-H", `x-goog-api-key: ${API_KEY}`, "-d", body, ]; const result = execFileSync("curl", curlArgs, { maxBuffer: 100 * 1024 * 1024, timeout: 310000 }); return extractImage(result.toString()); } async function generate(): Promise { const hasProxy = !!(process.env.HTTPS_PROXY || process.env.HTTP_PROXY || process.env.https_proxy || process.env.http_proxy); // Use curl when behind a proxy (Bun fetch has known proxy issues) if (hasProxy) return generateViaCurl(); return generateViaFetch(); } ``` ### Technical Analysis The image-generation script obtains a Google or Gemini API key from the process environment. However, the destination receiving that credential is also controlled thro ...[truncated 2504 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:76
Finding

Unpinned Bun Package Is Downloaded and Executed Through npx

Content
View full analysis
Remediation
View remediation
... ``` 3. Verify package provenance and integrity. Use a lockfile and registry integrity metadata where feasible, and document the expected package publisher and checksum. 4. Avoid automatic confirmation with `-y` in security-sensitive instructions. Show the resolved package name and version and obtain explicit user approval before downloading executable code. 5. Prefer an already installed Node.js runtime if the script can be made compatible, eliminating the need to download a runtime at invocation time. 6. Run downloaded tooling with a minimal environment and filesystem permissions. Do not expose unrelated credentials to the subprocess. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (22)

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

This section explicitly states that the skill derives behavior from a Claude account UUID read from the local Keychain. Accessing identity material from secure local credential storage is a high-sensitivity operation; even if the README claims the UUID never leaves the machine, the skill context pairs this access with external AI image generation, creating a meaningful privacy and data-handling risk.

Content

Scanner excerpt · README.md (reported line 108)May include surrounding context.

How It Works

text
Your Claude account UUID (from local Keychain)
       ↓
 + SALT "friend-2026-401"
       ↓

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The privacy section normalizes reading from the user's local Keychain by saying it happens "only" locally, but local-only credential access is still sensitive and should be treated as privileged. The reassuring wording may reduce user caution while the skill still accesses identity data and may combine it with external API usage, making this context more dangerous rather than safer.

Content

Scanner excerpt · README.md (reported line 124)May include surrounding context.

md
## Privacy

- Your account UUID **never leaves your machine**
- The skill reads from YOUR local Keychain only
- Only the image prompt is sent to Google's API (no personal data)
- The card shows a hash ID, not your actual account

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

Listing macOS Keychain access as a requirement confirms the skill depends on retrieving sensitive local identity information to function. Requiring credential-store access for a cosmetic card-generation feature is disproportionate to the task and increases the security impact of accidental or unsafe invocation.

Content

Scanner excerpt · README.md (reported line 140)May include surrounding context.

md
## Requirements

- macOS (needs Keychain access for your Claude identity)
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) installed and logged in
- Free `GOOGLE_API_KEY` ([get one here](https://aistudio.google.com/apikey))
- Node.js or Bun (for the buddy algorithm script)

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This skill directs the agent to read a Claude OAuth token from the user's macOS Keychain, then use it to call an authenticated API. Even if framed as needed to derive a Buddy identity, accessing and using a bearer token is highly sensitive because the token can authorize account access and could be mishandled, logged, or repurposed.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill tells the agent to extract a Claude OAuth token from Keychain and transmit it in an Authorization header to a remote endpoint, but provides no meaningful privacy or security warning. This is dangerous because it normalizes credential exfiltration behavior for a novelty feature and could expose account access if the token is intercepted, logged, or reused.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

Fetch the accountUuid from the API (try with proxy first for users behind VPN):

bash
PROFILE=$(curl -sS --max-time 10 -H "Authorization: Bearer $TOKEN" "https://api.anthropic.com/api/oauth/profile" 2>/dev/null)
UUID=$(echo "$PROFILE" | python3 -c "import json,sys; print(json.load(sys.stdin)['account']['uuid'])")

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The skill explicitly depends on Keychain access for Claude identity, which means it is designed to reach into a protected credential store to retrieve sensitive authentication material. For a novelty card generator, that context makes the capability disproportionate and materially more dangerous than in a legitimate account-management workflow.

Content

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

md
## Requirements

- macOS (needs Keychain access for Claude identity)
- Claude Code logged in (OAuth token in Keychain)
- `GOOGLE_API_KEY` env var (free tier is enough — Gemini image gen)
- Node.js or Bun (for buddy algorithm + image generation)

Env Variable Harvesting

High
Category
Data Exfiltration
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.

Content

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

md
## Requirements

- macOS (needs Keychain access for Claude identity)
- Claude Code logged in (OAuth token in Keychain)
- `GOOGLE_API_KEY` env var (free tier is enough — Gemini image gen)
- Node.js or Bun (for buddy algorithm + image generation)

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

Referencing access to the local macOS Keychain indicates potential credential or secret retrieval behavior. In an agent skill context, any unnecessary access to local secret storage is especially sensitive because users may install and run skills with elevated trust, and the page's reassuring phrasing ('Only you have access') downplays the risk rather than warning about it.

Content

Scanner excerpt · site/index.html (reported line 97)May include surrounding context.

html
<div class="step">
        <div class="num">1</div>
        <h3>Your Identity</h3>
        <p>Reads your Claude account UUID from your local macOS Keychain. Only you have access.</p>
      </div>
      <div class="step">
        <div class="num">2</div>

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 56)May include surrounding context.

You need a free Google API key for image generation:

  1. Go to aistudio.google.com/apikey
  2. Click "Create API Key" (free, no credit card)
  3. Add it to your terminal:
bash

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README advertises broad natural-language invocation phrases like "generate my buddy card" and "what's my buddy?", which can cause the skill to activate unintentionally in ordinary conversation. Because the skill claims it will read local Keychain identity data and write an output file, accidental triggering increases the chance of privacy-impacting actions without clear user intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The usage section describes that the skill will read account identity from the local Keychain and save a file to ~/Downloads, but it does not present this as an explicit warning or consent boundary. Users may invoke the skill without realizing it accesses sensitive local identity material and persists output to disk, which undermines informed consent for local-data access.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

This line performs external transmission to an authenticated Anthropic profile endpoint using a bearer token obtained from local credentials. External transmission is especially dangerous here because the transmitted data and authorization context are sensitive, and the skill's purpose is decorative rather than operationally necessary.

Content

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

Fetch the accountUuid from the API (try with proxy first for users behind VPN):

bash
PROFILE=$(curl -sS --max-time 10 -H "Authorization: Bearer $TOKEN" "https://api.anthropic.com/api/oauth/profile" 2>/dev/null)
UUID=$(echo "$PROFILE" | python3 -c "import json,sys; print(json.load(sys.stdin)['account']['uuid'])")

External Transmission

Medium
Category
Data Exfiltration
Confidence
99% confidence
Finding

The fallback sends the same authenticated request through a local proxy (127.0.0.1:1082), increasing the attack surface because another local process can observe or manipulate sensitive traffic. Routing bearer-token-backed requests through an arbitrary proxy is particularly risky without verification, consent, or threat-model justification.

Content

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

If that fails (SSL/timeout), retry with common proxy:

bash
PROFILE=$(curl -sS --max-time 10 -x http://127.0.0.1:1082 -H "Authorization: Bearer $TOKEN" "https://api.anthropic.com/api/oauth/profile" 2>/dev/null)

Step 2: Generate Buddy data

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill requires use of a GOOGLE_API_KEY for external image generation, which expands the credential surface for a non-essential decorative feature. Exposing or mishandling that key could allow unauthorized API usage, quota theft, or billing abuse.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
80% confidence
Finding

The skill instructs use of npx -y bun, which can fetch and execute an unpinned package version at runtime. That creates a supply-chain risk: a compromised or changed upstream package could execute arbitrary code on the user's machine during skill use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill advises users to persist a Google API key in shell startup files without warning that such files may be broadly readable, backed up, synced, or exposed through logs and dotfile sharing. This increases the likelihood of long-term credential leakage for an otherwise optional capability.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The file embeds Chinese-language labels for species, hats, rarities, and stats in string literals, which indicates a built-in locale assumption. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The page explicitly states that the skill reads the user's Claude account UUID from the local macOS Keychain, but it does not present this as sensitive credential material or clearly explain what is collected, why it is needed, where it is processed, and whether it is stored or transmitted. In the context of an install page for an agent skill, normalizing secret-store access without strong consent and disclosure increases the risk of credential misuse and privacy compromise.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The page says the card is generated 'with AI' and also claims to derive identity from a local UUID, but it does not disclose whether user-derived data is sent to an external model or image-generation service. That omission prevents informed consent and could expose identifiers or derived profile data to third parties.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The example species display includes non-English localized text "果冻" even though the skill does not state that outputs may be localized or ask the user for a language preference. This can violate language/locale policy when a specific language is imposed without opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

The document declares lang="en" and all visible user-facing content is English, with no indication of alternative language support or user opt-in. Under the stated policy, forcing a specific language without user choice can be a natural-language locale policy violation.

Content

No source excerpt is available for this finding.