Back to skill

Security audit

Setup Agent

Security checks for vulnerabilities and agentic risk

Overview

This Karma setup skill performs expected login setup, but it handles API keys in ways that could expose them or create unsafe persistent shell changes.

Review this skill before installing. It is not clearly malicious, but you should avoid saving the key to shell startup files unless you understand the exposure, avoid echoing the full key into chat, and only run verification against the intended Karma HTTPS endpoint or a trusted local development server.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:139
Finding
API Key Exfiltration Through an Unvalidated Configurable Endpoint<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 139-149 **Vulnerability Type**: Arbitrary credential destination / unvalidated API endpoint **Risk Level**: High ### Complete Code Snippet ```bash ## 2. Set the API URL (Optional) Defaults to production. For local development: export KARMA_API_URL="http://localhost:3002" ## 3. Verify Configuration curl -s "${KARMA_API_URL:-https://gapapi.karmahq.xyz}/v2/agent/info" \ -H "x-api-key: ${KARMA_API_KEY}" \ -H "X-Source: skill:setup-agent" -H "X-Invocation-Id: $INVOCATION_ID" -H "X-Skill-Version: 0.2.0" \ | python3 -m json.tool ``` The same configurable base URL is also used when registering a new agent: ```bash BASE_URL="${KARMA_API_URL:-https://gapapi.karmahq.xyz}" INVOCATION_ID=$(uuidgen) curl -s -X POST "${BASE_URL}/v2/agent/register" \ -H "Content-Type: application/json" \ -H "X-Source: skill:setup-agent" -H "X-Invocation-Id: $INVOCATION_ID" -H "X-Skill-Version: 0.2.0" \ -d '{}' ``` ### Technical Analysis The verification request sends `KARMA_API_KEY` in an HTTP header to a destination controlled by the inherited `KARMA_API_URL` environment variable. The Skill does not validate the URL scheme, hostname, port, or resolved destination before transmitting the credential. Although endpoint configurability can be legitimate for local development, accepting an arbitrary inherited URL for authenticated requests exceeds the minimum privileges necessary for normal production setup. In particular, the documented configuration permits plaintext HTTP and does not distinguish loopback development services from arbitrary remote hosts. An attacker able to influence the process environment, shell configuration, workspace configuration, or agent execution context can redirect the verification request to a server under the attacker's control. ### Attack Path 1. The attacker causes `KARMA_API_URL` to be set to an attacker-controlled endpoint. 2. The Skill obtains or loads a valid `KA ...[truncated 768 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Restrict authenticated production requests to an explicit allowlist of approved HTTPS hostnames. 2. Parse and validate `KARMA_API_URL` before use, including its scheme, hostname, port, and user-information component. 3. Reject plaintext HTTP except when the destination is an explicitly permitted loopback address used for local development. 4. Require informed user confirmation before sending a credential to any non-production endpoint. 5. Display the resolved destination without exposing the key before making an authenticated request. 6. Avoid inheriting security-sensitive endpoint overrides silently. Prefer an explicit command option or trusted configuration file with restrictive permissions. 7. Consider separating production and development flows so production credentials cannot be sent to development endpoints. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:101
Finding
Shell Startup Command Injection Through Unsafe API Key Persistence<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 101-136 **Vulnerability Type**: Persistent shell command injection **Risk Level**: High ### Complete Code Snippet ```markdown - **I already have a key** → ask for the key, skip to [Save Your API Key](#1-save-your-api-key) ``` ```bash # Detect shell config file if [ -f "$HOME/.zshrc" ]; then SHELL_RC="$HOME/.zshrc" elif [ -f "$HOME/.bashrc" ]; then SHELL_RC="$HOME/.bashrc" fi # Append only if not already present grep -q 'KARMA_API_KEY' "$SHELL_RC" || echo '\n# Karma API Key\nexport KARMA_API_KEY="karma_..."' >> "$SHELL_RC" # Also export for current session export KARMA_API_KEY="karma_..." ``` The Skill additionally instructs the agent to replace an existing value: ```markdown If the key already exists in the file, replace the old value instead of appending a duplicate. ``` ### Technical Analysis The instructions direct the agent to place user-provided or server-provided key material inside an executable shell startup file. No strict format validation or shell-safe serialization is required before interpolation. If a key contains a double quote, command substitution, newline, backtick, or other shell syntax, it may terminate or alter the intended `export` assignment. The injected syntax would then be evaluated whenever the affected `.bashrc` or `.zshrc` file is sourced. This is particularly dangerous when combined with the configurable endpoint behavior: a malicious registration endpoint could return a crafted value in the JSON `key` field, which the Skill may subsequently treat as a legitimate credential and persist. The write is presented as permanent credential storage rather than persistence for attacker code. Nevertheless, unsafe interpolation creates a path to cross-session code execution under the user's account. ### Attack Path 1. The attacker supplies a crafted string through the “I already have a key” flow, or causes a redirected registration endpoint to return a m ...[truncated 1043 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate every key against a strict, documented allowlist pattern before exporting or storing it, for example `^karma_[A-Za-z0-9]+$` if that accurately reflects the server specification. 2. Reject values containing whitespace, quotes, backticks, dollar signs, backslashes, newlines, control characters, or unexpected punctuation. 3. Never construct shell startup statements through direct textual interpolation. 4. If shell configuration must be used, serialize the value with a proven shell-quoting routine and update only a clearly delimited managed block. 5. Prefer an operating-system credential manager or a dedicated credential file readable only by the user instead of executable shell startup files. 6. Create credential files with restrictive permissions such as `0600`, and verify ownership before writing. 7. Parse registration responses as JSON and validate both the response schema and key format before persistence. 8. Back up the startup file before modification and perform an atomic update to avoid corruption. 9. Ask for explicit user approval while identifying the exact file that will be modified. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:112
Finding
API Key Exposed in Plaintext Shell Configuration and Conversation Output<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 112-171 **Vulnerability Type**: Plaintext credential exposure **Risk Level**: Medium ### Complete Code Snippet ```bash # Append only if not already present grep -q 'KARMA_API_KEY' "$SHELL_RC" || echo '\n# Karma API Key\nexport KARMA_API_KEY="karma_..."' >> "$SHELL_RC" # Also export for current session export KARMA_API_KEY="karma_..." ``` The success instructions explicitly direct the agent to repeat the key: ```markdown If the response includes `walletAddress` and `supportedActions`, tell the user their API key and that they're ready: > Your Karma agent is ready! > > **API Key**: `karma_...` (the key from step 1 or the email flow) > > You can now use these skills: > - `project-manager` — Create and manage projects, grants, milestones, and updates > - `find-funding-opportunities` — Search for grants, hackathons, bounties, and more ``` ### Technical Analysis The Skill stores a reusable API credential as plaintext in `.bashrc` or `.zshrc`, which are executable configuration files commonly included in backups, diagnostic archives, dotfile repositories, and support bundles. The instructions do not require checking file ownership or permissions. The Skill also directs the agent to reproduce the complete key in its final response after successful verification. This is unnecessary because the user already provided or received the credential. Repeating it expands the credential's exposure to conversation history, agent telemetry, screenshots, transcripts, and retained support data. Exporting the key globally from a shell startup file also makes it available to every descendant process launched from that shell, including processes that do not need Karma access. This violates least-exposure principles for sensitive credentials. ### Attack Path 1. The user approves persistent storage or completes the setup flow. 2. The key is written to a shell startup file and repeated in the agent convers ...[truncated 749 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not repeat the complete API key in the final response. Display only a masked identifier, such as the last four characters. 2. Prefer an operating-system credential manager, secret service, or dedicated secrets tool for persistent storage. 3. If file-based storage is unavoidable, use a dedicated file with mode `0600`, verify ownership, and avoid placing secrets in executable startup files. 4. Load the credential only for commands that require Karma access rather than exporting it to all descendant processes. 5. Warn users explicitly about plaintext persistence and obtain informed consent. 6. Add key rotation and revocation instructions for suspected exposure. 7. Ensure logs, error messages, command traces, and agent telemetry redact the API key. 8. Avoid passing the key on command lines, where it could appear in process listings or shell history. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

External Script Fetching

High
Category
Supply Chain
Content
## 3. Verify Configuration

```bash
curl -s "${KARMA_API_URL:-https://gapapi.karmahq.xyz}/v2/agent/info" \
  -H "x-api-key: ${KARMA_API_KEY}" \
  -H "X-Source: skill:setup-agent" -H "X-Invocation-Id: $INVOCATION_ID" -H "X-Skill-Version: 0.2.0" \
  | python3 -m json.tool
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The condition "before first use of any Karma skill" is ambiguous and delegates invocation to a broad stateful heuristic rather than a clear user intent. This can cause the skill to run preemptively and request or store secrets even when the user has not asked to authenticate yet.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The condition "before first use of any Karma skill" is ambiguous and delegates invocation to a broad stateful heuristic rather than a clear user intent. This can cause the skill to run preemptively and request or store secrets even when the user has not asked to authenticate yet.

External Transmission

Medium
Category
Data Exfiltration
Content
BASE_URL="${KARMA_API_URL:-https://gapapi.karmahq.xyz}"
INVOCATION_ID=$(uuidgen)

curl -s -X POST "${BASE_URL}/v2/agent/register" \
  -H "Content-Type: application/json" \
  -H "X-Source: skill:setup-agent" -H "X-Invocation-Id: $INVOCATION_ID" -H "X-Skill-Version: 0.2.0" \
  -d '{}'
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill instructs the agent to display the user's API key back in the success message, unnecessarily exposing a sensitive credential in the chat transcript. Chat logs may be retained, shared, or inspected later, so echoing the full key increases the risk of credential theft and account compromise.

Natural-Language Policy Violations

Low
Confidence
77% confidence
Finding
The file prescribes fixed English user-facing text for the confirmation message and does not indicate that the language should follow the user's preference. This can violate language or locale policies when users have not opted into English-only responses.

Static analysis

No suspicious patterns detected.