T09 · Insecure Skill Coding Practices
- Location
scripts/click_element.sh:3- Finding
Hard-Coded PinchTab Bearer Credential Enables Unauthorized Browser Control
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
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.
scripts/click_element.sh:3Hard-Coded PinchTab Bearer Credential Enables Unauthorized Browser Control
scripts/decode_screenshot.py:44Predictable Screenshot Output Permits Symlink File Overwrite and Sensitive-Image Retention
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).
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
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.
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.
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).
"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
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.
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.
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.
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.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
data=$(jq -n --arg selector "$1" '{selector: $selector}')
curl -X POST "$URL" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "$data"
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.
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.
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.
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.
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.
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.
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}
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
"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!")
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.
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.
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.
data=$(jq -n --arg url "$1" '{url: $url}')
curl -X POST "$URL" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "$data"
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.
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.
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.
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.
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}")
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.
Detected: suspicious.exposed_secret_literal, suspicious.potential_exfiltration