Back to skill

Security audit

BotSee

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real BotSee API client, but it needs Review because saved API keys can be sent to an arbitrary environment-selected API host and the skill exposes non-interactive billing and destructive account actions.

Install only if you trust BotSee and are comfortable with an agent managing your BotSee account, spending credits, storing an API key locally, and making remote account changes. Do not set BOTSEE_BASE_URL except for a trusted BotSee-controlled endpoint, avoid pasting live API keys into chat, and require explicit user approval before top-up, archive, delete, or analysis commands that spend credits.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/botsee.py:19
Finding

Unrestricted API Base URL Override Can Exfiltrate Stored Credentials

Content
View full analysis

Vulnerability Details

File Location: scripts/botsee.py, lines 19 and 99-121
Vulnerability Type: Attacker-controlled network destination for authenticated requests
Risk Level: Medium

Vulnerable Code

python
# API Configuration
BASE_URL = os.environ.get("BOTSEE_BASE_URL", "https://botsee.io")
python
def api_call(method, endpoint, data=None, api_key=None, timeout=30, params=None, extra_headers=None):
    """Make an API call to BotSee. Returns (response_dict, http_status)."""
    url = f"{BASE_URL}/api/v1{endpoint}"
    if params:
        query = urllib.parse.urlencode(params)
        url = f"{url}?{query}"

    headers = {"Content-Type": "application/json"}
    if api_key:
        headers["Authorization"] = f"Bearer {api_key}"
    if extra_headers:
        headers.update(extra_headers)

    body = json.dumps(data).encode() if data else None
    req = urllib.request.Request(url, data=body, headers=headers, method=method)

    # Create SSL context with certificate validation
    ssl_context = ssl.create_default_context()
    ssl_context.check_hostname = True
    ssl_context.verify_mode = ssl.CERT_REQUIRED

    try:
        with urllib.request.urlopen(req, timeout=timeout, context=ssl_context) as resp:

Technical Analysis

The destination of every API request is controlled by the BOTSEE_BASE_URL environment variable without validation of its scheme, hostname, port, or origin. Authenticated operations subsequently add the API key loaded from ~/.botsee/config.json to the request as an Authorization: Bearer header.

Consequently, a process environment controlled by an attacker can redirect authenticated requests to an arbitrary server. The override also accepts an http:// URL. Although the code creates a certificate-validating SSL context, that context does not provide transport security when the selected URL uses plaintext HTTP.

The same generic request fu ...[truncated 2408 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the production override where possible. Use a fixed, trusted API origin for released Skill packages:

    python
    BASE_URL = "https://botsee.io"
    
  2. If development overrides are required, enforce an explicit allowlist. Parse and validate the URL before any request:

    python
    from urllib.parse import urlparse
    
    ALLOWED_API_ORIGINS = {
        "https://botsee.io",
        "https://staging.botsee.io",
    }
    
    candidate = os.environ.get("BOTSEE_BASE_URL", "https://botsee.io").rstrip("/")
    parsed = urlparse(candidate)
    
    if parsed.scheme != "https" or candidate not in ALLOWED_API_ORIGINS:
        raise RuntimeError("BOTSEE_BASE_URL is not an approved HTTPS API origin")
    
    BASE_URL = candidate
    
  3. Never send secrets based solely on a configurable URL. Before attaching Authorization, payment-signature, or other sensitive headers, verify that the final parsed request origin exactly matches an approved origin.

  4. Reject plaintext HTTP. Require HTTPS for every non-loopback endpoint. If local development must support HTTP, require an explicit development mode and prevent real API keys or payment proofs from being used in that mode.

  5. Prevent cross-origin redirect leakage. Disable automatic redirects for authenticated requests or validate every redirect target before forwarding authorization and payment headers.

  6. Separate authenticated and unauthenticated clients. Use dedicated request functions or policies for signup calls, authenticated API operations, and payment-proof submission so each sends only the minimum required headers.

  7. Document the override as security-sensitive. Clearly warn users that changing the API origin can disclose credentials and should only be used with trusted local or staging services.

  8. Add automated security tests. Confirm that HTTP URLs, unapproved domains, crafted ports, user-info URLs, and red ...[truncated 80 chars]

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (30)

Tainted flow: 'req' from os.environ.get (line 113, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The CLI builds request URLs from BOTSEE_BASE_URL, which is taken directly from the environment and then used for authenticated network requests. An attacker who can influence the environment can redirect requests to an attacker-controlled host and capture the Bearer API key and any submitted data; TLS validation does not help when the attacker controls the destination and presents a valid certificate for that host.

Content

Scanner excerpt · scripts/botsee.py (reported line 121)May include surrounding context.

python
ssl_context.verify_mode = ssl.CERT_REQUIRED

    try:
        with urllib.request.urlopen(req, timeout=timeout, context=ssl_context) as resp:
            raw = resp.read()
            response_data = json.loads(raw) if raw else {}
            payment_headers = extract_payment_headers(resp.headers)

Self-Modification

High
Category
Rogue Agent
Confidence
90% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · CHANGELOG.md (reported line 11)May include surrounding context.

md
- Removed passive API key detection from SKILL.md to eliminate prompt injection vector;
  keys are now retrieved programmatically via /botsee signup-status
- Removed self-update mechanism (cmd_update, download_github_release, install_update)
  to eliminate supply chain risk from unverified GitHub downloads; updates are handled
  via the plugin marketplace

Tool Parameter Abuse

High
Category
Tool Misuse
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).

Content

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

Reset configuration:

bash
rm ~/.botsee/config.json        # Remove user config
rm .context/botsee-config.json  # Remove workspace config
/botsee setup <domain>          # Start fresh

Tool Parameter Abuse

High
Category
Tool Misuse
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).

Content

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

Reset configuration:

bash
rm ~/.botsee/config.json        # Remove user config
rm .context/botsee-config.json  # Remove workspace config
/botsee setup <domain>          # Start fresh

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared purpose is passive monitoring, but the documented behavior includes account creation, payment flows, API key storage, persistent configuration changes, content generation, and file writes. This mismatch can mislead users or automated reviewers into granting trust or execution approval for a skill that performs materially broader and riskier actions than advertised.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The README explicitly tells users to paste a live API key into chat, which encourages disclosure of a secret to the model interface and any associated chat storage, telemetry, or logs. In an agent-skill context this is more dangerous than ordinary docs because users are being instructed to hand credentials to an LLM-mediated workflow rather than entering them through a dedicated secret input path.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

This is a direct social-engineering pattern: the documentation asks the user to disclose a sensitive credential in natural language to the assistant. Because the model may retain, transform, summarize, or expose chat content through logs and integrations, this creates unnecessary credential exposure risk.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The repeated signup instructions normalize giving a live API key to the assistant and persisting it automatically, increasing the chance users will expose production credentials in conversation history. Repetition in onboarding makes misuse more likely and broadens exposure across common usage paths.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
91% confidence
Finding

The workflow states that Claude will automatically save the pasted API key, creating deliberate session persistence of a secret obtained through chat. Persisting credentials captured from conversational input increases the blast radius of a transcript leak, local compromise, or accidental reuse across workspaces.

Content

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

Step 2: Visit the URL, complete signup, and paste your API key in the chat

Claude will automatically save it for you

Step 3: Create your site

/botsee create-site https://example.com

text

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The markdown states that /botsee delete-question <uuid> will delete a question permanently, but provides no caution that the operation is destructive. For user-data-affecting actions, the skill description should warn users when an action cannot be undone or may remove work permanently.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill invokes Python scripts that can access shell, network, local files, environment state, and persist data, but it declares no explicit tool scope or permission boundary. In an agent setting, that omission weakens reviewability and can cause operators to approve a skill without realizing it can make networked changes, save credentials, and write files.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

The skill persists operational state across sessions via ~/.botsee/config.json and .context/botsee-config.json, including API keys and active site/configuration data. Session persistence is not inherently malicious, but in an agent workflow it can create hidden state, surprise future runs, and expose credentials or prior context to later tasks and users on the same environment.

Content

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

md
**Sites:**
- /botsee list-sites             - List all sites
- /botsee get-site [uuid]        - View site details
- /botsee create-site <domain>   - Create a new site
- /botsee archive-site [uuid]    - Archive a site

**Customer Types:**

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill states that signup status automatically saves the API key to ~/.botsee/config.json, but this persistence is not prominently warned about in the skill description or safety notes. Silent credential persistence increases the chance of users exposing secrets through backups, shared machines, permissive file permissions, or later agent access to that file.

Content

No source excerpt is available for this finding.

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 · scripts/botsee.py (reported line 115)May include surrounding context.

python
body = json.dumps(data).encode() if data else None
    req = urllib.request.Request(url, data=body, headers=headers, method=method)

    # Create SSL context with certificate validation
    ssl_context = ssl.create_default_context()
    ssl_context.check_hostname = True
    ssl_context.verify_mode = ssl.CERT_REQUIRED

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description frames the tool as monitoring brand AI visibility, but the implementation also performs state-changing actions: creating resources, updating them, archiving/deleting them, billing top-ups, and generating/saving content. In an agent setting, this scope mismatch increases the chance that a caller invokes destructive or billable actions without understanding that the skill can mutate local state, remote account state, and spend credits.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The delete-question command permanently deletes remote data immediately, with no confirmation step or safety interlock. In an agent or automation context, a mistaken invocation, prompt confusion, or parameter mix-up can cause irreversible loss of user data with little friction.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill’s declared purpose is narrow monitoring of AI visibility, but the implementation also exposes account signup, payment/top-up, API-key handling, and broad administrative operations. This scope mismatch can mislead users and agents into granting trust or autonomy beyond what the manifest suggests, increasing the chance of unintended financial or administrative actions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documented workflow includes payment initiation and top-up operations even though the stated skill purpose is brand visibility monitoring. Financial operations are materially more sensitive than analytics, and hiding them inside a monitoring skill raises the risk that an agent or user triggers spending without realizing the skill handles billing flows.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill exposes broad create/update/archive/delete capabilities for sites, customer types, personas, and questions, which goes well beyond passive monitoring. In an agent context, this expanded write surface increases the chance of unintended state changes, duplicate objects, or destructive operations being performed under a misleadingly narrow description.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
78% confidence
Finding

The skill persists sensitive operational state in user-level configuration files, including API keys and site identifiers, and encourages reuse across sessions. Session persistence is not inherently malicious, but storing credentials and operational context on disk increases exposure if local permissions are weak, multiple agents share the environment, or later prompts/actions reuse state in unintended ways.

Content

Scanner excerpt · skills/botsee/SKILL.md (reported line 28)May include surrounding context.

md
**Sites:**
- /botsee list-sites             - List all sites
- /botsee get-site [uuid]        - View site details
- /botsee create-site <domain>   - Create a new site
- /botsee archive-site [uuid]    - Archive a site

**Customer Types:**

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

Archive operations are destructive state-changing actions, yet the documentation provides no warning or confirmation guidance before invoking them. In an agent workflow this can lead to accidental resource archival through misunderstanding, bad parsing, or prompt manipulation, especially because the command surface is broad and administrative.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The delete-question command permanently removes data but is documented without any destructive-use warning or confirmation requirement. For autonomous or semi-autonomous agents, omission of safeguards makes accidental deletion more likely and can cause avoidable data loss.

Content

No source excerpt is available for this finding.

Ssd 3

Low
Category
Not specified by scanner
Confidence
73% confidence
Finding

This example normalizes providing personally identifying information directly in the conversation so the assistant can perform account creation steps. While less sensitive than an API key, it is still an instruction to collect and use user-provided private data through natural-language workflow guidance.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The status example displays part of a live-style API key and normalizes showing credentials in command output. Even partial secrets can leak identifying information, encourage unsafe operator behavior, and end up in screenshots or logs in shared environments.

Content

No source excerpt is available for this finding.

Excessive Permissions

Low
Category
Privilege Escalation
Confidence
80% confidence
Finding

Skill requests more permissions than appear necessary for its stated functionality. Review if elevated access is justified.

Content

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

User Config (~/.botsee/config.json)

  • Purpose: Stores API key and site UUID
  • Permissions: 0o600 (owner read/write only)
  • Created by: /botsee setup command
  • Contents:
    json

Static analysis

No suspicious patterns detected.