Back to skill

Security audit

知乎热搜

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent Zhihu hot-topic command-line tool that fetches public GitHub-hosted data, with ordinary cache/export side effects and a display-sanitization caveat.

Install only if you are comfortable with a Chinese-language CLI that fetches public Zhihu archive data from GitHub and stores cache files in ~/.cache/zhihu-hot. Use --export with deliberate output paths because it can overwrite files, and treat terminal or Markdown output as untrusted if the upstream data source is compromised.

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

Warning
Location
zhihu-hot.py:121
Finding

Unsanitized Remote Content Enables Terminal Escape-Sequence Injection

Content
View full analysis
str: req = urllib.request.Request( url, headers=headers or {"User-Agent": "Mozilla/5.0 (compatible; ZhihuHotBot/3.0)"} ) with urllib.request.urlopen(req, timeout=30) as resp: return resp.read().decode("utf-8") ``` Parsed remote titles and URLs are stored unchanged: ```python for title, url in items: result["hot_search"].append({ "title": title, "url": url, "decoded_url": decode_url(url) }) ``` The resulting values are written directly to the terminal: ```python for i, item in enumerate(items, 1): title = item["title"] if get_display_width(title) > 38: title = title[:18] + ".." lines.append(f"│ {i:2d} │ {pad_string(title, 40)} │") ``` Other output paths similarly interpolate remote values without sanitization: ```python lines.append(f"{colorize(str(i).rjust(2), 'yellow')}. {item['title']}") ``` ```python lines.append(f" {i:2d}. {title} ({count}天)") ``` ### Technical Analysis The application treats Markdown retrieved from a remote GitHub repository as trusted display data. Titles, update times, and URLs extracted from that content can contain terminal control characters, including ANSI and OSC escape sequences. These characters are preserved by parsing and formatting and are subsequently emitted to the user's terminal. The existing `colorize` function only adds application-controlled ANSI sequences. It does not remove attacker-controlled control characters from remote values. Length truncation also does not provide protection because a malicious escape sequence can fit within the truncated portion. If the up ...[truncated 1672 chars]
Remediation
View remediation
str: value = ANSI_ESCAPE_RE.sub("", value) return "".join( ch for ch in value if ch in "\n\t" or (ord(ch) >= 0x20 and not 0x7F <= ord(ch) <= 0x9F) ) ``` For single-line fields, remove newlines and tabs as well. A mature terminal-sanitization library is preferable to a custom regular expression where available. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
analyze-month.py:26
Finding

Monthly Report Tool Emits Unsanitized Remote Titles to Terminal and Markdown

Content
View full analysis
str: req = urllib.request.Request(url, headers=headers or {"User-Agent": "Mozilla/5.0"}) with urllib.request.urlopen(req, timeout=30) as resp: return resp.read().decode("utf-8") ``` Parsed titles are retained without sanitization: ```python items = re.findall(r"\d+\.\s*\[([^\]]+)\]\(([^)]+)\)", hot_section.group(1)) result["hot_search"] = [{"title": t, "url": u} for t, u in items] ``` Remote titles are then interpolated directly into the generated Markdown report: ```python for i, (title, count) in enumerate(data["top_titles"], 1): lines.append(f"| {i} | {title} | {count} |") ``` ### Technical Analysis The monthly analysis tool considers remotely supplied titles safe for both terminal output and Markdown generation. No output-context encoding is performed. A malicious title containing control characters remains active when the report is printed to a terminal. In addition, Markdown metacharacters such as pipes, line breaks, brackets, and embedded HTML are not escaped. Consequently, an attacker controlling upstream archive data could alter the structure or presentation of the generated report. Markdown injection is context dependent: a renderer that permits raw HTML, external images, or active links may expose users to tracking or deceptive content when the generated report is viewed. Terminal escape sequences remain relevant because the entire report is printed to standard output. ### Attack Path 1. An attacker modifies an upstream archive entry for a month that a user analyzes. 2. The entry title contains terminal escape sequences, Markdown table delimiters, line breaks, links, or ...[truncated 1141 chars]
Remediation
View remediation
str: value = sanitize_terminal_text(value) value = value.replace("\\", "\\\\") value = value.replace("|", "\\|") value = value.replace("\r", " ").replace("\n", " ") return value ``` Apply this function to `title`, extracted keywords, and any other remote value before interpolation into the report. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The documented purpose does not fully match the described behavior: it presents itself as a simple Zhihu hot-list retrieval skill, while the analysis indicates dependence on GitHub API/Raw resources and possible missing or inconsistent search support. This kind of description-behavior mismatch is dangerous because users and policy systems may approve or invoke the skill under incomplete assumptions about external data flows, capabilities, and outputs.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill documentation advertises capabilities that imply network access, local cache reads, and file export/write behavior, but it does not declare any explicit tool scope or permissions boundary. In an agent environment, missing scope declarations can cause overbroad execution trust and make it harder for users or orchestrators to understand that the skill may access the network and modify local files.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The module docstring presents the tool name and description only in Chinese, which imposes a specific language on users. The policy requires flagging language or locale constraints when the skill does not offer user choice or clearly justify the restriction.

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 · analyze-month.py (reported line 19)May include surrounding context.

python
BASE_URL = "https://raw.githubusercontent.com/SnailDev/zhihu-hot-hub/main"
ARCHIVES_BASE = f"{BASE_URL}/archives"
GITHUB_TREE_API = "https://api.github.com/repos/SnailDev/zhihu-hot-hub/git/trees/main?recursive=1"

# 缓存
CACHE_DIR = os.path.expanduser("~/.cache/zhihu-hot")

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 · zhihu-hot.py (reported line 31)May include surrounding context.

python
BASE_URL = "https://raw.githubusercontent.com/SnailDev/zhihu-hot-hub/main"
ARCHIVES_BASE = f"{BASE_URL}/archives"
GITHUB_TREE_API = "https://api.github.com/repos/SnailDev/zhihu-hot-hub/git/trees/main?recursive=1"

# 缓存
CACHE_DIR = os.path.expanduser("~/.cache/zhihu-hot")

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The markdown instructs users to export files and clear caches without warning that these actions write to disk or delete local cached data. While not inherently malicious, this can lead to unintended local file modification or data loss, especially in automated agent workflows where users may not realize a command has side effects.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This codebase presents its description and all CLI help/output in Chinese, which effectively fixes the skill to a specific language/locale. The file does not indicate user opt-in, alternative locale support, or a documented justification for the constraint.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest describes a data retrieval and analysis tool for Zhihu hot topics, which implies read-oriented operations on the dataset. However, the implementation also writes output to arbitrary file paths via --export and creates/modifies cache files under the user's home directory, adding local persistence behavior not reflected in the description.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.