Back to skill

Security audit

Zh Tencent Novnc Chromium Cdp

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent remote-browser purpose, but it asks for broad root-level control and creates persistent remote access that users should review carefully before installing.

Install only on a disposable or dedicated host, not a production server or machine with sensitive accounts. Avoid giving SSH passwords or blanket passwordless sudo; prefer running reviewed commands yourself. Keep noVNC off the public Internet unless protected by SSH tunnel, VPN, TLS, strong access control, and firewall source restrictions, and disable/remove the services when finished.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
Findings (7)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:57
Finding

Agent instruction hierarchy and browser tool hijacking

Content
View full analysis
Remediation
View remediation

T06 · System Persistence

Error
Location
SKILL.md:504
Finding

Persistent privileged remote-browser services

Content
View full analysis
/etc/systemd/system/xvfb.service <<'EOF' [Unit] Description=Xvfb virtual display :99 After=network.target [Service] Type=simple ExecStart=/usr/bin/Xvfb :99 -screen 0 1920x1080x24 -ac Restart=always RestartSec=3 [Install] WantedBy=multi-user.target EOF cat > /etc/systemd/system/x11vnc.service <<'EOF' [Unit] Description=x11vnc server on :99 (password protected) After=xvfb.service Requires=xvfb.service [Service] Type=simple Environment=DISPLAY=:99 ExecStart=/usr/bin/x11vnc -display :99 -forever -shared -rfbauth /root/.vncpasswd -rfbport 5900 -quiet Restart=always RestartSec=3 [Install] WantedBy=multi-user.target EOF cat > /etc/systemd/system/novnc.service <<'EOF' [Unit] Description=noVNC websockify on 6080 After=x11vnc.service Requires=x11vnc.service [Service] Type=simple ExecStart=/usr/local/bin/websockify --web=/opt/noVNC 6080 localhost:5900 Restart=always RestartSec=3 [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable --now xvfb.service x11vnc.service novnc.service chromium-remote.service ``` ### Technical Analysis The Skill writes four system-wide systemd units and enables them immediately and at every subsequent boot. The services maintain a virtual display, VNC server, Internet-reachable noVNC gateway, and Chromium browser containing persistent user data. Persistence is related to the advertised convenience feature, but the Skill makes it mandatory rather than optional. It does not provide a complete uninstall procedure, expiration mechanism, or automatic shutdown after the requested task. The services are also installed at the system level instead of under a dedicated unprivileged user. ### Attack Path 1. The Agent obtains root or unrestricted sudo access. 2. The Skill writes service definitions under `/etc/systemd/system`. ...[truncated 744 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:256
Finding

Unrestricted passwordless root privilege grant

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:186
Finding

Unnecessary cloud instance metadata probing

Content
View full analysis
/dev/null | grep -q .; then echo "ENV_TYPE=CLOUD" elif curl -s --connect-timeout 2 http://100.100.100.200/latest/meta-data/ 2>/dev/null | grep -q .; then echo "ENV_TYPE=CLOUD" elif curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/ 2>/dev/null | grep -q .; then echo "ENV_TYPE=CLOUD" fi ``` ### Technical Analysis The Skill directly contacts Tencent Cloud, Alibaba Cloud, and common link-local cloud metadata endpoints solely to determine whether the host is a cloud server. Cloud metadata services may expose instance identity documents, configuration, and temporary credentials at related paths. The current commands query only metadata roots and pipe the response to `grep`; the audit found no confirmed request for credential-specific paths and no confirmed exfiltration of metadata. Nevertheless, this access is unnecessary for installing a browser and creates an avoidable interaction with a sensitive cloud credential service. ### Attack Path 1. The Skill runs on a cloud instance. 2. It sends unauthenticated HTTP requests to local cloud metadata services. 3. The metadata service returns instance-related content. 4. The response is consumed by the shell pipeline to classify the host. 5. A future or compromised Skill revision could reuse this trusted access pattern to query credential paths. ### Impact Assessment In the reviewed version, the direct impact is limited to unnecessary metadata access and environmental disclosure. No credential theft was confirmed. However, the capability touches services that may provide temporary cloud credentials, so extension or modification of these requests could expose cloud identity and account resources ava ...[truncated 32 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:396
Finding

Public noVNC service uses plaintext transport and retained plaintext credentials

Content
View full analysis
/root/.novnc_password chmod 600 /root/.novnc_password x11vnc -storepasswd "$NOVNC_PASS" /root/.vncpasswd chmod 600 /root/.vncpasswd ``` ```ini [Service] Type=simple ExecStart=/usr/local/bin/websockify --web=/opt/noVNC 6080 localhost:5900 Restart=always RestartSec=3 ``` ```bash PUBLIC_IP=$(curl -4 -s https://ifconfig.me 2>/dev/null || curl -4 -s https://api.ipify.org 2>/dev/null || true) if [ -n "$PUBLIC_IP" ]; then NOVNC_URL="http://${PUBLIC_IP}:6080/vnc.html" fi cat /root/.novnc_password ``` The response template sends both values to the user: ```text - noVNC address: http://:6080/vnc.html - noVNC access password: ``` ### Technical Analysis The noVNC gateway listens on TCP 6080 and is advertised through plaintext HTTP rather than HTTPS. The generated password is only eight alphanumeric characters, is retained in plaintext under `/root`, and is copied into the Agent conversation. File mode `0600` protects the local plaintext file from non-root users, but it does not protect the credential from root processes, Agent transcripts, platform logs, backups, or accidental disclosure. Plain HTTP/WebSocket access also lacks transport confidentiality and server authentication. The VNC authentication format may additionally impose effective password-length limitations depending on the x11vnc/VNC implementation, making reliance on this password unsuitable for direct Internet exposure. ### Attack Path 1. The Skill opens TCP 6080 and advertises a public HTTP URL. 2. The password is stored in plaintext and sent through the conversation. 3. An attacker obtains the password from a transcript, log, backup, privileged lo ...[truncated 575 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:443
Finding

Root-owned Chromium runs with its security sandbox disabled

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
SKILL.md:296
Finding

Unpinned third-party components are installed and executed with elevated privileges

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (19)

Cloud Metadata Access

High
Category
Server-Side Request Forgery
Confidence
93% confidence
Finding

The skill accesses an internal Alibaba metadata IP to detect cloud environment. Even though the immediate intent is environment detection, internal metadata endpoints are privileged network resources and contacting them expands the attack surface for SSRF-like behavior and cloud information disclosure.

Content

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

md
# 检测是否云服务器(腾讯云/阿里云/AWS metadata)
  if curl -s --connect-timeout 2 http://metadata.tencentyun.com/latest/meta-data/ 2>/dev/null | grep -q .; then
    echo "ENV_TYPE=CLOUD"
  elif curl -s --connect-timeout 2 http://100.100.100.200/latest/meta-data/ 2>/dev/null | grep -q .; then
    echo "ENV_TYPE=CLOUD"
  elif curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/ 2>/dev/null | grep -q .; then
    echo "ENV_TYPE=CLOUD"

Cloud Metadata Access

High
Category
Server-Side Request Forgery
Confidence
95% confidence
Finding

The skill probes cloud metadata endpoints, including 169.254.169.254, to classify the environment. Requests to metadata services are sensitive because they can expose cloud instance details or credentials if the probing is expanded, redirected, or repurposed, and normalizing metadata access in a skill is risky.

Content

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

md
echo "ENV_TYPE=CLOUD"
  elif curl -s --connect-timeout 2 http://100.100.100.200/latest/meta-data/ 2>/dev/null | grep -q .; then
    echo "ENV_TYPE=CLOUD"
  elif curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/ 2>/dev/null | grep -q .; then
    echo "ENV_TYPE=CLOUD"
  # 检测是否 NAS(群晖 Synology / QNAP 威联通)
  elif [ -f /etc/synoinfo.conf ]; then

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

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

bash
if [ "$(id -u)" = "0" ]; then
  echo "PERMISSION_OK: 当前是 root 用户"
elif command -v sudo >/dev/null 2>&1 && sudo -n true 2>/dev/null; then
  echo "PERMISSION_OK: 当前用户可免密 sudo"
else
  echo "PERMISSION_DENIED: 当前用户不是 root,且无法免密 sudo。"

Chaining Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

Piping a generated sudoers rule directly into sudo tee automates a highly privileged configuration change with no scoping and no validation. In an agent context, this is especially dangerous because it lowers friction for granting unrestricted root-equivalent access through a single copied command.

Content

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

引导用户在服务器终端执行一行命令即可,密码不离开用户机器:

bash
echo "$(whoami) ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/hermes-deploy

完成后 Agent 即可通过 sudo 继续部署。部署完成后执行 sudo rm /etc/sudoers.d/hermes-deploy 收回权限。

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

echo "$(whoami) ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/hermes-deploy

text

完成后 Agent 即可通过 `sudo` 继续部署。部署完成后执行 `sudo rm /etc/sudoers.d/hermes-deploy` 收回权限。

**备选:提供 SSH 凭证**

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill explicitly asks for SSH credentials as a fallback and does not place strong, repeated warnings around highly sensitive credential handling, redaction, or safer alternatives. This is dangerous because it normalizes collection of server passwords inside an agent workflow that also performs privileged remote administration and network exposure.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The invocation text tells the agent to automatically install and run a high-privilege remote browser stack with very broad trigger wording and minimal user scoping. Because the skill provisions services, opens ports, and configures persistence, an overly broad activation path raises the chance of unintended execution on the wrong host or in the wrong context.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
- **可视化浏览器**:Chromium 运行在 Xvfb 虚拟屏幕上,用户可通过 noVNC 网页实时查看画面。
- **AI 可控**:Agent 通过 CDP 连接 `127.0.0.1:9223`,可执行打开网页、点击、输入、读取页面、截图等操作。
- **人机协作**:遇到登录、二维码、滑块、验证码时,用户可在 noVNC 中手动处理,处理完成后 AI 继续执行。
- **权限预检**:安装前先确认 root/sudo 权限,权限不足时主动提醒用户授权方式,避免半安装状态。
- **安全边界**:默认只建议开放 noVNC 的 `6080/tcp`,CDP 调试端口 `9223/tcp` 不建议暴露到公网。
- **完成反馈**:部署完成后,Agent 必须先主动发送 noVNC 访问地址、访问密码、开机自启状态和端口开放提醒;截图作为最后一步补充确认发送,截图失败不得阻塞前面的核心信息。
- **Windows 本机模式**:Agent 自动启动 Edge/Chrome 远程调试端口,通过 CDP 接管浏览器,本机屏幕实时可见,截取当前页面反馈,无需安装额外组件。

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
- **可视化浏览器**:Chromium 运行在 Xvfb 虚拟屏幕上,用户可通过 noVNC 网页实时查看画面。
- **AI 可控**:Agent 通过 CDP 连接 `127.0.0.1:9223`,可执行打开网页、点击、输入、读取页面、截图等操作。
- **人机协作**:遇到登录、二维码、滑块、验证码时,用户可在 noVNC 中手动处理,处理完成后 AI 继续执行。
- **权限预检**:安装前先确认 root/sudo 权限,权限不足时主动提醒用户授权方式,避免半安装状态。
- **安全边界**:默认只建议开放 noVNC 的 `6080/tcp`,CDP 调试端口 `9223/tcp` 不建议暴露到公网。
- **完成反馈**:部署完成后,Agent 必须先主动发送 noVNC 访问地址、访问密码、开机自启状态和端口开放提醒;截图作为最后一步补充确认发送,截图失败不得阻塞前面的核心信息。
- **Windows 本机模式**:Agent 自动启动 Edge/Chrome 远程调试端口,通过 CDP 接管浏览器,本机屏幕实时可见,截取当前页面反馈,无需安装额外组件。

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

bash
if [ "$(id -u)" = "0" ]; then
  echo "PERMISSION_OK: 当前是 root 用户"
elif command -v sudo >/dev/null 2>&1 && sudo -n true 2>/dev/null; then
  echo "PERMISSION_OK: 当前用户可免密 sudo"
else
  echo "PERMISSION_DENIED: 当前用户不是 root,且无法免密 sudo。"

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

bash
if [ "$(id -u)" = "0" ]; then
  echo "PERMISSION_OK: 当前是 root 用户"
elif command -v sudo >/dev/null 2>&1 && sudo -n true 2>/dev/null; then
  echo "PERMISSION_OK: 当前用户可免密 sudo"
else
  echo "PERMISSION_DENIED: 当前用户不是 root,且无法免密 sudo。"

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
99% confidence
Finding

The skill instructs the user to grant full passwordless sudo to the current account via a sudoers drop-in. This creates a powerful privilege-escalation path that can be abused by any process or later prompt execution under that account, far beyond the immediate deployment need.

Content

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

引导用户在服务器终端执行一行命令即可,密码不离开用户机器:

bash
echo "$(whoami) ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/hermes-deploy

完成后 Agent 即可通过 sudo 继续部署。部署完成后执行 sudo rm /etc/sudoers.d/hermes-deploy 收回权限。

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
90% confidence
Finding

The skill stores the generated noVNC password in cleartext at /root/.novnc_password for later disclosure. Even though root-only permissions reduce exposure, plaintext credential storage on disk increases the risk of credential theft through backups, later compromise, or accidental disclosure by the agent.

Content

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

md
# 8 位随机密码(字母+数字混合)
NOVNC_PASS=$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 8)
echo -n "$NOVNC_PASS" > /root/.novnc_password
chmod 600 /root/.novnc_password

# 用 x11vnc 自己的工具生成 VNC 密码文件
x11vnc -storepasswd "$NOVNC_PASS" /root/.vncpasswd

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
# 用 x11vnc 自己的工具生成 VNC 密码文件
x11vnc -storepasswd "$NOVNC_PASS" /root/.vncpasswd
chmod 600 /root/.vncpasswd

echo "noVNC 访问密码已生成:$NOVNC_PASS"
echo "明文存储于:/root/.novnc_password(仅 root 可读)"

Session Persistence

Medium
Category
Rogue Agent
Confidence
91% confidence
Finding

The skill enables persistent systemd services for a remote browser, VNC server, and websockify listener at boot. Persistence magnifies risk because exposed services and privileged browser automation remain available after reboot, potentially outside the user's immediate awareness.

Content

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

EOF

systemctl daemon-reload systemctl enable --now xvfb.service x11vnc.service novnc.service chromium-remote.service

text

验证(应全部 `active`):

Internal Network Request

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

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

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

md
import websocket

url = 'https://example.com'
tabs = json.load(urllib.request.urlopen('http://127.0.0.1:9223/json'))
page = next(t for t in tabs if t.get('type') == 'page')
ws = websocket.create_connection(
    page['webSocketDebuggerUrl'],

Internal Network Request

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

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

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

md
import websocket

url = 'https://example.com'
tabs = json.load(urllib.request.urlopen('http://127.0.0.1:9223/json'))
page = next(t for t in tabs if t.get('type') == 'page')
ws = websocket.create_connection(
    page['webSocketDebuggerUrl'],

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

bash
DISPLAY=:99 import -window root /tmp/remote-browser.png
mkdir -p ~/.openclaw/media/qqbot
cp /tmp/remote-browser.png ~/.openclaw/media/qqbot/remote-browser.png

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

bash
DISPLAY=:99 import -window root /tmp/remote-browser.png
mkdir -p ~/.openclaw/media/qqbot
cp /tmp/remote-browser.png ~/.openclaw/media/qqbot/remote-browser.png