Back to skill

Security audit

Md To Zhihu

Security checks for vulnerabilities and agentic risk

Overview

The skill largely does what it says, but it stores reusable Zhihu login cookies in plaintext and uses debug-controlled browser sessions for authenticated publishing.

Review before installing. Use it only if you are comfortable letting a script control an authenticated Zhihu session and publish or draft articles. Keep the skill directory private, avoid committing or sharing generated .zhihu_cookies.json or .zhihu_browser_profile data, prefer draft mode first, and do not preview or publish Markdown from untrusted sources without sanitizing it.

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

Error
Location
scripts/publish.py:34
Finding

Zhihu Authentication Cookies Are Persisted in Plaintext

Content
View full analysis
list | None: """Load cookies from file, return None if not found.""" if COOKIE_FILE.exists(): try: return json.loads(COOKIE_FILE.read_text(encoding="utf-8")) except (json.JSONDecodeError, IOError): return None return None ``` ### Technical Analysis After browser login, the script serializes the complete Playwright browser cookie list into `scripts/.zhihu_cookies.json`. This list may include the reusable `z_c0` authentication cookie, the `_xsrf` token, and other cookies belonging to the Zhihu browser context. The file is stored as ordinary plaintext without: - Owner-only file permissions - Encryption or operating-system credential protection - Filtering to retain only the cookies strictly required for publishing - Automatic expiration or secure deletion - A repository ignore rule protecting generated credential files The related browser profile is also persisted under `scripts/.zhihu_browser_profile`. Persisting authentication state is necessary to support repeat publishing without logging in each time, but storing all captured cookies in the project directory exceeds the minimum credential scope needed for that function. Network use itself is consistent with the declared functionality: the inspected code transmits credentials and article content only to hard-coded HTTPS endpoints under `www.zhihu.com` and `zhuanlan.zhihu.com`. No unrelated exfiltration destination was found. ### Attack ...[truncated 1192 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/convert.py:659
Finding

Untrusted Markdown Can Inject Executable HTML into Generated Preview Files

Content
View full analysis
{title} ``` ```html
{body_html}
``` ### Technical Analysis Python-Markdown permits raw HTML in Markdown input. BeautifulSoup parses and rewrites HTML structure, but it is not an HTML security sanitizer. Consequently, elements and attributes such as the following can survive conversion: - `
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (17)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented behavior is inconsistent with the analyzed implementation and instructions: it claims one-click publishing and API-oriented publication support while also describing additional undeclared directory-wide conversion and local preview/clipboard functionality. Behavior mismatches are dangerous because users and orchestrators may authorize the skill for a narrow purpose, while the actual workflow may touch more files than expected or fail open into manual/browser-based steps involving cookies and local content handling.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill advertises operational behavior that implies file access, shell execution, and networked publishing, but it does not declare any explicit tool scope or permissions boundaries. In an agent environment, missing scope declarations can cause overbroad execution authority or make reviewers unaware that the skill may read local files, write outputs, invoke package installers, and access Zhihu/login endpoints.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest says the skill can 'one-click publish articles' to Zhihu, but this file only converts markdown into HTML, writes local output files, and provides copy/paste guidance for manual publishing. There is no Zhihu API client, authentication flow, browser automation, or network request implementing article publication.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The docstring for convert_to_zhihu_content states that the output 'is used by the publisher for API-based article creation,' implying an integrated publishing path. In this file, the function merely returns transformed HTML, and the CLI only saves files and prints that the content 'can be used' for API publishing, without any API call or publishing action.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The generated document hard-codes <html lang="zh-CN">, which imposes a specific language/locale in the output. This file also uses exclusively Chinese user-facing UI strings throughout the generated preview, but does not offer an opt-in, override, or explain that the tool is limited to Chinese-language workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Authentication cookies are written in plaintext JSON to a predictable local file without permission hardening or explicit user warning. Anyone with local access to the file could reuse the session cookies to impersonate the user on Zhihu, making this a direct credential exposure risk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code explicitly states it uses a real browser with remote debugging to 'completely avoid automation detection.' Deliberately bypassing platform anti-automation controls is risky because it normalizes stealthy authenticated automation and may facilitate abuse, account restrictions, or session hijacking when combined with persistent cookies and CDP access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The browser is launched with remote debugging enabled and no explicit safety notice, despite the debugging interface granting deep control over the browser session. In this skill, that session includes login to Zhihu and access to persistent profile data, so users are exposed to a significant local-session compromise risk without informed consent.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

The code launches a real browser with a fixed remote debugging port and a persistent profile directory. Remote debugging exposes powerful browser control and access to authenticated session data; if another local process can reach the port, it could hijack the Zhihu session or extract cookies. The skill context increases risk because it is explicitly handling authenticated publishing and storing persistent login state.

Content

Scanner excerpt · scripts/publish.py (reported line 137)May include surrounding context.

python
user_data_dir = str(_get_user_data_dir())

    # Launch real browser with remote debugging and a dedicated profile
    chrome_proc = sp.Popen(
        [
            browser_exe,
            f"--remote-debugging-port={debug_port}",

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · scripts/publish.py (reported line 285)May include surrounding context.

python
headers["x-xsrftoken"] = xsrf

    # Step 1: Create empty draft
    resp = requests.post(
        "https://zhuanlan.zhihu.com/api/articles/drafts",
        headers=headers,
        json={"title": title, "delta_time": 0},

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · scripts/publish.py (reported line 285)May include surrounding context.

python
headers["x-xsrftoken"] = xsrf

    # Step 1: Create empty draft
    resp = requests.post(
        "https://zhuanlan.zhihu.com/api/articles/drafts",
        headers=headers,
        json={"title": title, "delta_time": 0},

Tainted flow: 'headers' from requests.post (line 331, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/publish.py (reported line 285)May include surrounding context.

python
headers["x-xsrftoken"] = xsrf

    # Step 1: Create empty draft
    resp = requests.post(
        "https://zhuanlan.zhihu.com/api/articles/drafts",
        headers=headers,
        json={"title": title, "delta_time": 0},

Tainted flow: 'headers' from requests.post (line 331, network input) → requests.patch (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/publish.py (reported line 306)May include surrounding context.

python
_print(f"草稿已创建: ID={draft_id}")

    # Step 2: Update draft with content
    resp2 = requests.patch(
        f"https://zhuanlan.zhihu.com/api/articles/{draft_id}/draft",
        headers=headers,
        json={

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · scripts/publish.py (reported line 358)May include surrounding context.

python
if topic_ids:
        publish_data["topic_ids"] = topic_ids

    resp = requests.put(
        f"https://zhuanlan.zhihu.com/api/articles/{draft_id}/publish",
        headers=headers,
        json=publish_data,

Tainted flow: 'headers' from requests.post (line 331, network input) → requests.put (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/publish.py (reported line 358)May include surrounding context.

python
if topic_ids:
        publish_data["topic_ids"] = topic_ids

    resp = requests.put(
        f"https://zhuanlan.zhihu.com/api/articles/{draft_id}/publish",
        headers=headers,
        json=publish_data,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

This fallback path again starts a real browser with remote debugging enabled, creating the same local attack surface during publishing. Because it then injects authenticated cookies and opens the authoring page, compromise of the debugging session can lead directly to account takeover or unauthorized publishing.

Content

Scanner excerpt · scripts/publish.py (reported line 428)May include surrounding context.

python
debug_port = 9223  # Different port to avoid conflict
    user_data_dir = str(_get_user_data_dir())

    chrome_proc = sp.Popen([
        browser_exe,
        f"--remote-debugging-port={debug_port}",
        f"--user-data-dir={user_data_dir}",

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest describes converting markdown articles and one-click publishing articles to Zhihu, which reads as a per-article workflow. This file adds a batch mode that enumerates a directory and publishes all .md files with delays, a materially broader operational scope than the manifest description communicates.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.