Back to skill

Security audit

Skills Browser

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent local skill browser, but it exposes local skill contents too broadly and has unsafe server and launcher behavior that should be reviewed before use.

Review or patch this before installing. At minimum, bind the server to 127.0.0.1, remove wildcard CORS, validate skill IDs against enumerated directories, sanitize rendered Markdown or disable raw HTML, and replace the port-kill behavior with a safe conflict message or verified graceful shutdown.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
server/server.py:82
Finding

Local Skill Data Exposed Through All-Interface Binding and Permissive CORS

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
server/server.py:43
Finding

Path Traversal in Skill Detail API

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
server/index.html:634
Finding

Stored DOM Cross-Site Scripting Through Unsanitized Markdown

Content
View full analysis
' + fallbackMarkdownParser(text) + ''; } try { // Use the configured marked.js parser const result = window.marked.parse(text); console.log("[Markdown] Result length:", result.length, "Has hljs class:", result.includes('hljs')); return '
' + result + '
'; } catch (e) { console.error("[Markdown] Error with marked.js:", e); return '
' + fallbackMarkdownParser(text) + '
'; } } ``` ```javascript const resp = await fetch(API_BASE + "/api/skill/" + skillId); const data = await resp.json(); detailPanel.innerHTML = '
' + '
' + '
' + escapeHtml(data.frontmatter.name || skillId) + '
' + (data.frontmatter.BusinessSupportVersion ? '
v' + escapeHtml(data.frontmatter.BusinessSupportVersion) + '
' : '') + '
' + (data.frontmatter.description ? '
' + escapeHtml(data.frontmatter.description) + '
' : '') + '
' + (data.frontmatter.Author ? '
Author ' + escapeHtml(data.frontmatter.Author) + '
' : '') + ...[truncated 2218 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
skillsbrowser.sh:7
Finding

Launcher Forcefully Terminates Unrelated Processes on Port 8765

Content
View full analysis
/dev/null ``` ### Technical Analysis The launcher enumerates every process using port 8765 and sends each process `SIGKILL`. It does not verify that a target process was previously started by this Skill, belongs to the expected user, or is an instance of `server.py`. `SIGKILL` prevents the target from running shutdown handlers, flushing state, or releasing resources cleanly. Terminating arbitrary port owners is unnecessary for the declared functionality and exceeds the minimum process-control authority required to start a local browser service. ### Attack Path 1. An unrelated application binds to port 8765. 2. The user runs `skillsbrowser.sh`. 3. `lsof -ti:8765` returns the unrelated application's process ID. 4. `xargs kill -9` immediately terminates that process. 5. The unrelated application cannot perform cleanup or save pending state. ### Impact Assessment The behavior can cause: - Denial of service against unrelated local applications. - Loss of unsaved work or in-memory state. - Data corruption where the terminated process was performing writes. - Unexpected termination of multiple processes if more than one process is associated with the port. The command operates with the launcher's user privileges. It does not independently escalate privileges, but it violates process isolation and least-privilege expectations. ]]>
Remediation
View remediation
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared purpose and implementation evidence do not match: the skill claims a local HTML/Python browser, but analysis indicates undeclared Markdown parsing/rendering and code that does not clearly correspond to the stated UI stack. Such mismatches are risky because hidden or undeclared functionality can mask content injection, unsafe rendering, or other behavior that users and reviewers would not expect from a simple local browser.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill-detail endpoint uses user-controlled skill_id directly in os.path.join(SKILL_DIR, skill_id, "SKILL.md") without validation or canonicalization. An attacker can supply path traversal sequences such as ../ to escape the intended skills directory and read arbitrary files named SKILL.md elsewhere on disk, which exceeds the justified capability of a local browser for skills.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill metadata declares no tool scope or permission boundaries even though the analyzed package is reported to include file read, network, and shell-capable behavior. Missing explicit scope is dangerous because it prevents reviewers and enforcement layers from understanding or constraining what the skill may do, increasing the risk of unexpected filesystem access, command execution, or local service exposure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The document declares lang="zh-CN", and the visible UI text throughout the page is Chinese-only, which indicates the skill interface is fixed to a specific language. Under the policy, locale constraints should either be optional for the user or clearly documented as region-specific and justified.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · server/js/highlight.min.js (reported line 1171)May include surrounding context.

js
className:"string",endsParent:!0,variants:[{begin:/"/,end:/"/,contains:[a]},{
begin:/'/,end:/'/,contains:[a]},{begin:/[^\s"'=<>`]+/}]}]}]};return{
name:"HTML, XML",
aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],
case_insensitive:!0,unicodeRegex:!0,contains:[{className:"meta",begin:/<![a-z]/,
end:/>/,relevance:10,contains:[i,o,s,r,{begin:/\[/,end:/\]/,contains:[{
className:"meta",begin:/<![a-z]/,end:/>/,contains:[i,r,o,s]}]}]

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This endpoint serves skill metadata and full skill content from disk over HTTP with no authentication, authorization, or explicit user disclosure that local files are being exposed. In the context of a local skill browser this may seem expected, but it still creates an information exposure surface, especially when combined with network accessibility or embedding of sensitive data inside skill files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The server binds to 0.0.0.0, making the browser accessible on all network interfaces rather than only the local machine, while automatically opening a browser as if it were a local-only tool. This expands the attack surface to other hosts on the network, making the file-exposure endpoints materially more dangerous in this skill context.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script indiscriminately identifies any process bound to port 8765 and forcefully terminates it with kill -9 before starting its own server. This can kill unrelated local services, cause data loss or corruption by bypassing graceful shutdown, and creates a denial-of-service condition on the host beyond what is necessary for a simple skill browser.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Using kill -9 through xargs on any PID returned for port 8765 performs an immediate, non-interactive termination with no notice to the user. Because SIGKILL prevents cleanup handlers from running, this can disrupt unrelated applications, lose unsaved state, and make the behavior surprising and unsafe in a local developer environment.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The natural-language comments around the script's core behavior are written only in Chinese, which imposes a specific language without any opt-in or justification. This can violate language/locale policy expectations when the skill is intended for general use by a broader audience.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

Line L11 starts python3 server.py in the background, which is a subprocess execution with persistent effects, but the script gives no active output or warning to inform the user that a local server is being launched. The only nearby explanation is a comment in Chinese, which may not function as a clear disclosure for all users of the skill.

Content

No source excerpt is available for this finding.