Back to skill

Security audit

Browser Relay

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed local browser-control relay, but it gives an agent powerful access to a real Chromium session and handles tokens/screenshots in ways that need careful review.

Install only if you intend to let an agent control a local Chromium browser. Use a dedicated browser profile with no personal logins, stop the relay when done, protect the bearer token, avoid sending screenshots with sensitive content to Telegram, and review whether bypassing platform IP restrictions is acceptable for your use case.

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

T09 · Insecure Skill Coding Practices

Error
Location
start.sh:6
Finding

Predictable Temporary Files Permit Token Disclosure, Symlink Attacks, and PID Manipulation

Content
View full analysis
/dev/null; then kill "$pid" 2>/dev/null for i in $(seq 1 10); do kill -0 "$pid" 2>/dev/null || break sleep 0.5 done if kill -0 "$pid" 2>/dev/null; then kill -9 "$pid" 2>/dev/null fi echo "已停止旧进程 (PID: $pid)" fi rm -f "$RELAY_PID_FILE" fi } ``` ```bash nohup python3 -u relay.py > "$LOG_FILE" 2>&1 & RELAY_PID=$! echo "$RELAY_PID" > "$RELAY_PID_FILE" ``` ```python print(f" Auth token: {AUTH_TOKEN}") token_path = Path("/tmp/browser-relay-token") token_path.touch(mode=0o600, exist_ok=True) token_path.write_text(AUTH_TOKEN) os.chmod(token_path, stat.S_IRUSR | stat.S_IWUSR) ``` ### Technical Analysis The relay uses fixed, globally predictable paths under `/tmp` for its token, PID, and log files. Neither the shell script nor the Python implementation verifies that these paths are regular files owned by the current user and not symbolic links. The token file is opened through `Path.touch()` and `Path.write_text()`, both of which follow symbolic links. Applying `chmod()` afterward does not prevent the attack because the target may already have been overwritten. The operation can also unexpectedly change the permissions of the symlink target. The token is printed to standard output, while `start.sh` redirects standard output to `/tmp/relay.log`. The log is not explicitly created with restrictive perm ...[truncated 2262 chars]
Remediation
View remediation
/cmdline`, executable identity, process owner, and preferably process start time before sending a signal. 8. Use a supervisor or process handle instead of trusting a reusable numeric PID where possible. 9. Remove token and PID files during orderly shutdown and rotate the token after any suspected disclosure. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
relay.py:211
Finding

Unrestricted JavaScript Evaluation Exposes Browser Session Data and Authenticated Actions

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unpinned Python Dependencies Create a Mutable Supply-Chain Boundary

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (33)

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 · README.md (reported line 61)May include surrounding context.

md
TOKEN=$(cat /tmp/browser-relay-token)

# Health check
curl -s -H "Authorization: Bearer $TOKEN" http://localhost:18792/health

# List browser tabs
curl -s -H "Authorization: Bearer $TOKEN" http://localhost:18792/tabs

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description understates the actual power of the skill. Beyond screenshots, it exposes full browser automation plus arbitrary JavaScript execution in the user's logged-in browser context, which can access page content, cookies via JS where available, local/session storage, and drive authenticated actions on websites. In this context, the mismatch is dangerous because it can mislead users or upstream agents into granting a tool that effectively enables local browser takeover and data exfiltration.

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 84)May include surrounding context.

1. 检查 Chromium 是否运行

bash
curl -s http://127.0.0.1:9222/json/version

如果连接失败,说明 Chromium 未启动,需要启动它(见下方"启动 Chromium")。

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 84)May include surrounding context.

1. 检查 Chromium 是否运行

bash
curl -s http://127.0.0.1:9222/json/version

如果连接失败,说明 Chromium 未启动,需要启动它(见下方"启动 Chromium")。

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 174)May include surrounding context.

md
# 1. 截图并保存
TOKEN=$(cat /tmp/browser-relay-token)
SCREENSHOT_PATH="/tmp/relay_screenshot.png"
curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"quality":80}' http://127.0.0.1:18792/screenshot \
  | python3 -c "
import sys, json, base64

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The /evaluate endpoint exposes arbitrary JavaScript execution in whatever page the user's local Chromium has open. In a browser-relay skill, this enables full DOM access, data extraction, session abuse, and arbitrary in-page actions far beyond simple navigation or screenshots, making the relay effectively a remote browser RCE primitive within the user's authenticated web context.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

Arbitrary Runtime.evaluate access is an unjustified and dangerous capability for a relay advertised mainly for browser control and screenshots. It allows reading page content, invoking privileged web APIs available to the page, manipulating authenticated sessions, and bypassing any intended higher-level safety constraints in the relay API.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation explicitly frames the skill as a way for AI agents to control the user's local Chromium browser and bypass platform IP restrictions, but it does not clearly warn that this enables interaction with authenticated sessions, local browsing context, and user data. In this context, missing safety warnings materially increases the risk of misuse because an agent or operator may treat the relay as routine infrastructure rather than a highly privileged browser-control channel.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · README.md (reported line 61)May include surrounding context.

md
TOKEN=$(cat /tmp/browser-relay-token)

# Health check
curl -s -H "Authorization: Bearer $TOKEN" http://localhost:18792/health

# List browser tabs
curl -s -H "Authorization: Bearer $TOKEN" http://localhost:18792/tabs

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README explicitly documents a workflow that captures browser screenshots and uploads them to Telegram, but it does not warn users that screenshots may contain sensitive page content, session information, personal data, or other confidential material. In the context of a browser-control relay, this is materially risky because the tool is designed to operate on a user's real local browser session, making accidental third-party disclosure more likely.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

The direct reference to https://api.telegram.org/ confirms use of an external third-party endpoint for screenshot delivery. In a browser automation relay, this increases the risk of accidental data leakage because captured content from local browsing sessions can leave the host environment without adequate warning or consent controls.

Content

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

2. Send to Telegram

TG_BOT_TOKEN="your-bot-token" TG_CHAT_ID="your-chat-id" curl -s -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendPhoto"
-F "chat_id=${TG_CHAT_ID}"
-F "photo=@/tmp/relay_screenshot.png"

text

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

The direct reference to https://api.telegram.org/ confirms use of an external third-party endpoint for screenshot delivery. In a browser automation relay, this increases the risk of accidental data leakage because captured content from local browsing sessions can leave the host environment without adequate warning or consent controls.

Content

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

2. Send to Telegram

TG_BOT_TOKEN="your-bot-token" TG_CHAT_ID="your-chat-id" curl -s -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendPhoto"
-F "chat_id=${TG_CHAT_ID}"
-F "photo=@/tmp/relay_screenshot.png"

text

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest description and the entire operational guidance are written in Chinese, and the example input text also assumes Chinese usage. This creates a locale/language constraint for the skill without documenting user choice, opt-in, or a justified region-specific limitation.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · SKILL.md (reported line 84)May include surrounding context.

1. 检查 Chromium 是否运行

bash
curl -s http://127.0.0.1:9222/json/version

如果连接失败,说明 Chromium 未启动,需要启动它(见下方"启动 Chromium")。

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

Launching Chromium with nohup ... & creates a persistent background browser session beyond the immediate interaction. In this skill's context, that persistence matters because the browser may remain logged into user sites with remote debugging enabled, increasing the window during which local malware, another process, or later agent actions can control or inspect the session.

Content

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

2. 启动 Chromium(如果未运行)

bash
DISPLAY=:0 nohup chromium --remote-debugging-port=9222 --remote-allow-origins=* > /dev/null 2>&1 &

注意事项:

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

The screenshot flow extracts browser-rendered content from the user's local browser and writes it to a file, preparing it for later transmission. Even though the capture request is local, the skill context explicitly couples this with Telegram upload, so sensitive on-screen information from authenticated sessions can be collected and forwarded outside the host.

Content

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

md
# 1. 截图并保存
TOKEN=$(cat /tmp/browser-relay-token)
SCREENSHOT_PATH="/tmp/relay_screenshot.png"
curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"quality":80}' http://127.0.0.1:18792/screenshot \
  | python3 -c "
import sys, json, base64

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

The hardcoded use of https://api.telegram.org/ confirms an external data sink. Combined with browser automation and screenshot capture, this creates a direct path to move data from the user's local browser session to a remote service outside the user's machine and outside the platform's control.

Content

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

2. 通过 Telegram Bot API 发送图片

TG_BOT_TOKEN="<从 session_state 或 memory 获取>" TG_CHAT_ID="<从 session_state 或 memory 获取>" curl -s -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendPhoto"
-F "chat_id=${TG_CHAT_ID}"
-F "photo=@${SCREENSHOT_PATH}"

text

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

The hardcoded use of https://api.telegram.org/ confirms an external data sink. Combined with browser automation and screenshot capture, this creates a direct path to move data from the user's local browser session to a remote service outside the user's machine and outside the platform's control.

Content

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

2. 通过 Telegram Bot API 发送图片

TG_BOT_TOKEN="<从 session_state 或 memory 获取>" TG_CHAT_ID="<从 session_state 或 memory 获取>" curl -s -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendPhoto"
-F "chat_id=${TG_CHAT_ID}"
-F "photo=@${SCREENSHOT_PATH}"

text

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documentation and manifest indicate support for sending screenshots to Telegram, yet this file only returns base64 screenshot data over HTTP and contains no Telegram API calls or message-sending logic. This is a direct mismatch between the advertised behavior and the implemented functionality.

Content

No source excerpt is available for this finding.

Dynamic Request Target

Medium
Category
Server-Side Request Forgery
Confidence
60% confidence
Finding

Request target host is built from a dynamic or untrusted value. If the host is attacker-influenced, this enables SSRF to arbitrary internal or metadata endpoints.

Content

Scanner excerpt · relay.py (reported line 47)May include surrounding context.

python
async def get_tabs():
    session = await get_http_session()
    async with session.get(f"http://{CDP_HOST}:{CDP_PORT}/json") as resp:
        tabs = await resp.json()
    return [t for t in tabs if t.get("type") == "page"]

Dynamic Request Target

Medium
Category
Server-Side Request Forgery
Confidence
60% confidence
Finding

Request target host is built from a dynamic or untrusted value. If the host is attacker-influenced, this enables SSRF to arbitrary internal or metadata endpoints.

Content

Scanner excerpt · relay.py (reported line 276)May include surrounding context.

python
async def get_tabs():
    session = await get_http_session()
    async with session.get(f"http://{CDP_HOST}:{CDP_PORT}/json") as resp:
        tabs = await resp.json()
    return [t for t in tabs if t.get("type") == "page"]

Dynamic Request Target

Medium
Category
Server-Side Request Forgery
Confidence
60% confidence
Finding

Request target host is built from a dynamic or untrusted value. If the host is attacker-influenced, this enables SSRF to arbitrary internal or metadata endpoints.

Content

Scanner excerpt · relay.py (reported line 295)May include surrounding context.

python
async def get_tabs():
    session = await get_http_session()
    async with session.get(f"http://{CDP_HOST}:{CDP_PORT}/json") as resp:
        tabs = await resp.json()
    return [t for t in tabs if t.get("type") == "page"]

Dynamic Request Target

Medium
Category
Server-Side Request Forgery
Confidence
80% confidence
Finding

The /tab/new handler concatenates untrusted user input directly into the CDP /json/new query string. While this does not create classic arbitrary-destination SSRF, it does let an authenticated caller force the local browser to open arbitrary URLs, including internal network resources or sensitive local services, using the user's machine and browser context.

Content

Scanner excerpt · relay.py (reported line 285)May include surrounding context.

python
body = await request.json() if request.can_read_body else {}
    url = body.get("url", "about:blank") if body else "about:blank"
    session = await get_http_session()
    async with session.get(f"http://{CDP_HOST}:{CDP_PORT}/json/new?{url}") as resp:
        tab = await resp.json()
    return web.json_response({"id": tab["id"], "url": tab.get("url", "")})

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script prints the relay token directly to stdout when the service is already running, which can expose a bearer secret to shell history, terminal scrollback, shared logs, or calling processes. In this skill's context, the token appears to gate access to a relay that controls the user's local Chromium instance, so disclosure could enable unauthorized browser control and access to browsing context or screenshots.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.