Back to skill

Security audit

PinchTab

Security checks for vulnerabilities and agentic risk

Overview

This browser automation skill is mostly coherent, but it ships a hard-coded browser-control token and easy screenshot export paths that could expose sensitive browsing data.

Review before installing. Replace and rotate the embedded PinchTab token, prefer a per-user secret from an environment variable or secret store, and avoid using the Telegram or screenshot persistence workflows on pages containing credentials, account data, private messages, or internal information unless you explicitly intend to export that content.

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/click_element.sh:3
Finding

Hard-Coded PinchTab Bearer Credential Enables Unauthorized Browser Control

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/decode_screenshot.py:44
Finding

Predictable Screenshot Output Permits Symlink File Overwrite and Sensitive-Image Retention

Content
View full analysis
str: """Save decoded image to file""" path = Path(output_path) path.parent.mkdir(parents=True, exist_ok=True) with open(path, "wb") as f: f.write(image_bytes) ``` `scripts/decode_screenshot.py:93`: ```python parser.add_argument("--output", default="/tmp/pinchtab-screenshot.jpg", help="Output file path") ``` `scripts/decode_screenshot.py:102-105`: ```python base64_str, image_bytes = decode_screenshot(args.tab_id, args.server, args.token) # Save to file output_path = save_screenshot(image_bytes, args.output) ``` `scripts/screenshot_and_send.sh:25-26`: ```bash TEMP_DIR=$(mktemp -d) SCREENSHOT_FILE="$TEMP_DIR/screenshot.jpg" ``` `scripts/screenshot_and_send.sh:79-82`: ```bash if [ -d "/root/.openclaw/workspace/skills/pinchtab/assets" ]; then cp "$SCREENSHOT_FILE" "/root/.openclaw/workspace/skills/pinchtab/assets/last-screenshot.jpg" echo "📁 Copied to: /root/.openclaw/workspace/skills/pinchtab/assets/last-screenshot.jpg" fi ``` ### Technical Analysis The Python implementation uses the fixed default path `/tmp/pinchtab-screenshot.jpg` and opens it with ordinary write-and-truncate semantics. It does not use exclusive creation, verify ownership, reject symbolic links, or create a private temporary file. On a shared system, another local user or compromised process can create that path as a symbolic link before the script runs. Python's `open(path, "wb")` follows the link and truncates the destination if the account executing the Skill can write to it. The screenshot bytes are then written to the linked target. The fixed path ...[truncated 2863 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (24)

YARA rule 'agent_skill_credential_exfiltration_webhook': AI agent skill credential harvesting followed by webhook or external exfiltration [agent_skills]

Critical
Category
YARA Match
Confidence
85% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · scripts/decode_screenshot.py (reported line 20)May include surrounding context.

python
creenshot.py <tab_id> [--send-telegram <chat_id>] [--output <path>]
"""

import sys
import os
import base64
import json
import argparse
import subprocess
import requests
from pathlib import Path

def decode_screenshot(tab_id: str, server: str = "http://localhost:9867", token: str = "") -> tuple[str, bytes]:
    """Fetch and decode screenshot from PinchTab"""
    
    if not token:
        token = os.getenv("PINCHTAB_TOKEN", "")
    
    if not token:
        raise ValueError("PINCHTAB_TOKEN not set. Export it or pass via --token")
    
    print(f"📸 Fetching screenshot for tab: {tab_id}")
    
    headers = {"Authorization": f"Bearer {token}"}
    response = requests.get(f"{server}/tabs/{tab_id}/screenshot", headers=headers)
    
    if response.status_code != 200:
        raise Exception(f"PinchTab error: {response.status_code} - {response.text}")
    
    data = response.json()
    base64_str = data.get("base64")
    
    if not base64_str:
        raise ValueError("No base64 data

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documented behavior includes writing screenshots to local files and forwarding them externally, while the skill is presented mainly as browser automation/control. Hidden or under-disclosed storage and outbound sharing are dangerous because screenshots may contain credentials, personal data, or internal content, and users may not expect persistence or copying into workspace assets.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documented behavior includes writing screenshots to local files and forwarding them externally, while the skill is presented mainly as browser automation/control. Hidden or under-disclosed storage and outbound sharing are dangerous because screenshots may contain credentials, personal data, or internal content, and users may not expect persistence or copying into workspace assets.

Content

No source excerpt is available for this finding.

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · scripts/decode_screenshot.py (reported line 88)May include surrounding context.

python
"caption": caption or f"PinchTab Screenshot"
        }
        
        response = requests.post(url, files=files, data=data)
    
    if response.status_code == 200 and response.json().get("ok"):
        print("✅ Sent to Telegram!")
        return True
    else:
        print(f"❌ Telegram error: {response.text}")
        return False

def main():
    parser = argparse.ArgumentParser(
        description="Decode PinchTab base64 screenshots and optionally send to Telegram"
    )
    parser.add_argument("tab_id", help="PinchTab tab ID")
    parser.add_argument("--server", default="http://localhost:9867", help="PinchTab server URL")
    parser.add_argument("--token", help="PinchTab auth token (or set PINCHTAB_TOKEN)")
    parser.add_argument("--output", default="/tmp/pinchtab-screenshot.jpg", help="Output file path")
    parser.add_argument("--send-telegram", help="Send to Telegram (chat ID)")
    parser.add_argument("--telegram-token", help="Telegram bot token (or set TELEGRAM_BOT_TO

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill invokes shell scripts, uses environment variables, and performs networked browser/Telegram operations, but the manifest does not declare any tool scope or permissions boundaries. That makes the skill harder to audit and easier to run with broader-than-expected capabilities, increasing the risk of unintended command execution, network access, or secret use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill documentation instructs users to send screenshots to Telegram but provides no warning that page captures may contain sensitive data and will be transmitted to a third-party service. In a browser-automation context, screenshots can easily include tokens, account data, internal dashboards, or personal information, so the lack of privacy disclosure materially increases risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation embeds a live-looking bearer token directly in a markdown file, which is a credential exposure issue rather than just incomplete warning text. Even though the API is bound to localhost, any local process, malicious browser extension, or user with access to the skill package could reuse the token to drive the browser automation service, potentially navigating to attacker-controlled sites, extracting page content, or interacting with authenticated sessions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file describes populating username and password fields programmatically, but it does not include any warning about handling credentials or the privacy implications of automating login. Under the markdown criteria for missing user warnings, credential-related behavior should be disclosed because it can affect user privacy and account security.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/click_element.sh (reported line 13)May include surrounding context.

sh
data=$(jq -n --arg selector "$1" '{selector: $selector}')

curl -X POST "$URL" \
     -H "Authorization: Bearer $TOKEN" \
     -H "Content-Type: application/json" \
     -d "$data"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This shell script sends user-provided input to a local HTTP endpoint via curl, but there is no confirmation prompt, user-facing notice, or explanatory comment indicating that data will be transmitted. For code files, network calls that transmit user or system data should include some visible disclosure unless already clearly documented as part of the skill's stated purpose.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script extends a browser automation skill with an out-of-band third-party delivery channel to Telegram, which is outside the core browser-control function. In an agent-skill context, screenshots can contain credentials, session data, personal information, or proprietary content, so adding easy external export materially increases exfiltration risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script saves screenshots to disk at a predictable local path without warning users that browser screenshots may contain sensitive information. Local persistence can expose data to other local users, backup systems, forensic recovery, or accidental reuse if the file is not securely managed.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code implements direct upload of screenshots to Telegram using a bot token and chat ID, creating a ready-made third-party messaging path for sensitive browser data. Even if intended as a convenience feature, such functionality is risky in an automation skill because it normalizes exporting captured content outside the local/browser environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The optional Telegram upload sends screenshot contents to a third-party service without a strong privacy notice or trust-boundary warning. Screenshots from browser automation can include MFA codes, account pages, internal dashboards, or personal data, making external transmission especially sensitive.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

The script establishes external transmission to api.telegram.org, sending a locally saved screenshot to a third-party endpoint. In the context of a browser automation skill, outbound transfer of captured page imagery is a genuine data-exposure risk because screenshots often contain secrets or sensitive business information.

Content

Scanner excerpt · scripts/decode_screenshot.py (reported line 68)May include surrounding context.

python
print(f"📤 Sending to Telegram (chat: {chat_id})...")
    
    url = f"https://api.telegram.org/bot{bot_token}/sendPhoto"
    
    with open(image_path, "rb") as f:
        files = {"photo": f}

Tainted flow: 'data' from requests.get (line 33, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/decode_screenshot.py (reported line 77)May include surrounding context.

python
"caption": caption or f"PinchTab Screenshot"
        }
        
        response = requests.post(url, files=files, data=data)
    
    if response.status_code == 200 and response.json().get("ok"):
        print("✅ Sent to Telegram!")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script sends a bearer token in an HTTP request and also hardcodes that token directly in the file. Even though the destination is localhost, this creates credential exposure risk through source disclosure, shell history/process inspection, logs, or accidental reuse in less-trusted environments; anyone who obtains the token may be able to control the browser automation service and access page contents or perform actions in the browser context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script performs an authenticated HTTP POST to a local browser-control service using a hardcoded bearer token, with no prompting, warning, or validation. In the context of a browser automation skill, this can silently launch or control a browser instance and may expose browsing context or enable unintended automation if the script is invoked unexpectedly or the local service is not adequately isolated.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

The script embeds a long-lived bearer token directly in the file and sends it over plain HTTP to a localhost API. Hardcoded secrets are vulnerable to disclosure through source access, logs, backups, or reuse in other contexts; if the local service binds beyond loopback, is proxied, or runs in a shared environment, an attacker who obtains the token could drive the browser automation service and potentially access sensitive internal or authenticated content.

Content

Scanner excerpt · scripts/navigate_to_url.sh (reported line 13)May include surrounding context.

sh
data=$(jq -n --arg url "$1" '{url: $url}')

curl -X POST "$URL" \
     -H "Authorization: Bearer $TOKEN" \
     -H "Content-Type: application/json" \
     -d "$data"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code performs a network POST using user-provided input and an authorization token, but the script provides no confirmation prompt, explanatory comment, or user-facing notice about transmitting data to a local service. For code files, network calls that transmit user or system data should have some visible disclosure unless clearly documented as the skill's stated purpose, which is not evident in this file alone.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script can send captured browser screenshots to Telegram, which is an external third-party service unrelated to the core browser-control function. Screenshots may contain credentials, personal data, session details, or internal application content, so this creates a clear data exfiltration path if the script is run with a chat ID and bot token.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script transmits screenshot content to Telegram with only a generic status message and no explicit privacy or sensitivity warning. Because screenshots often contain confidential visual data, users may not appreciate that executing this path sends that data outside the local environment.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

This line performs an outbound network transmission to the Telegram API, sending a locally captured screenshot to an external service. In the context of a browser automation skill, external transmission of captured page content is security-relevant because it can leak sensitive browsing data outside the trusted environment.

Content

Scanner excerpt · scripts/screenshot_and_send.sh (reported line 60)May include surrounding context.

sh
if [ -n "$TELEGRAM_CHAT_ID" ] && [ -n "$TELEGRAM_BOT_TOKEN" ]; then
  echo "📤 Sending to Telegram (chat: $TELEGRAM_CHAT_ID)..."
  
  TELE_RESPONSE=$(curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendPhoto" \
    -F "chat_id=${TELEGRAM_CHAT_ID}" \
    -F "photo=@${SCREENSHOT_FILE}" \
    -F "caption=PinchTab Screenshot from tab ${TAB_ID}")

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

Copying screenshots into a fixed workspace path introduces local persistence of potentially sensitive browser contents beyond the immediate task. This increases the chance of unintended retention, later access by other tools or users, and accidental disclosure from a predictable location.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal, suspicious.potential_exfiltration

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/api-endpoints.md:9

Shell script base64-encodes a local file and sends it over the network.

Critical
Code
suspicious.potential_exfiltration
Location
scripts/screenshot_and_send.sh:46