Back to skill

Security audit

zhongjie

Security checks for vulnerabilities and agentic risk

Overview

This real-estate advisor skill is coherent, but it stores sensitive buyer data and map credentials behind a weak local web API and includes risky scraping code, so users should review it carefully before installing.

Before installing, assume the local workspace may contain sensitive family, budget, commute, school, and property-search information. Keep the server bound to localhost, do not expose the port on a network, restrict or rotate any AMap credentials, avoid using the WeChat fetcher until TLS validation and domain controls are fixed, and prefer pinned dependencies plus Markdown sanitization before relying on the dashboard.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/search_wechat.py:68
Finding
HTTPS Certificate Validation Is Globally Disabled for WeChat Search Requests<![CDATA[ ## Vulnerability Details **File Location**: `scripts/search_wechat.py:68-70` **Vulnerability Type**: Improper certificate validation **Risk Level**: High ### Vulnerable Code ```python _ssl_ctx = ssl.create_default_context() _ssl_ctx.check_hostname = False _ssl_ctx.verify_mode = ssl.CERT_NONE ``` This insecure SSL context is subsequently used for HTTPS requests, including: ```python with urllib.request.urlopen(req, timeout=timeout, context=_ssl_ctx) as resp: ``` ```python with urllib.request.urlopen(req, timeout=10, context=_ssl_ctx) as resp: ``` ```python opener = urllib.request.build_opener( urllib.request.HTTPSHandler(context=_ssl_ctx), _NoRedirectHandler(), ) ``` ### Technical Analysis The code explicitly disables both certificate-chain validation and hostname verification. Consequently, the client accepts self-signed, expired, untrusted, or hostname-mismatched certificates. These HTTPS requests carry user-provided property research keywords, receive Sogou cookies, process search results, and resolve redirect targets. Although the network access is necessary for the declared search functionality, disabling TLS validation is not necessary and exceeds the minimum safe networking behavior. An attacker capable of intercepting the network connection can impersonate Sogou or another requested HTTPS endpoint. The attacker can observe potentially sensitive search terms and replace returned search results, article URLs, cookies, or article content. Because retrieved information is saved as research and may be used to formulate property recommendations, modified responses can also compromise the integrity of subsequent advice. ### Attack Path 1. A user invokes `search_wechat.py` to research a property, school district, family requirement, or related topic. 2. The script opens an HTTPS connection using `_ssl_ctx`. 3. An attacker with a network interception position, malicious proxy, compromised access point, or manipulated DNS response pr ...[truncated 995 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the certificate-validation overrides and retain Python's secure defaults: ```python _ssl_ctx = ssl.create_default_context() ``` - Do not set `check_hostname` to `False` or `verify_mode` to `ssl.CERT_NONE`. - If a private certificate authority is genuinely required, load only the required trusted CA bundle: ```python _ssl_ctx = ssl.create_default_context(cafile="/path/to/trusted-ca.pem") ``` - Enforce an allowlist of expected HTTPS hosts, such as `weixin.sogou.com`, `v.sogou.com`, and `mp.weixin.qq.com`. - Validate redirect destinations before following or storing them. - Avoid forwarding cookies to any host other than the host that originally issued them. - Add automated tests confirming that self-signed and hostname-mismatched certificates are rejected. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/server.py:73
Finding
Unauthenticated Local API Exposes and Modifies Sensitive Customer Data<![CDATA[ ## Vulnerability Details **File Location**: `scripts/server.py:73-103` **Vulnerability Type**: Missing authentication combined with unrestricted CORS **Risk Level**: High ### Vulnerable Code ```python app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) ``` The application then exposes configuration and customer data without any authentication or authorization: ```python @app.get("/api/config") def get_config(): return { "amapKey": env.get("AMAP_JS_API_KEY", ""), "amapSecurityCode": env.get("AMAP_JS_API_SECURITY_CODE", ""), } @app.get("/api/preferences") def get_preferences(): path = data_dir / "data" / "preferences.md" if not path.exists(): return {"content": ""} return {"content": path.read_text(encoding="utf-8")} @app.put("/api/preferences") def save_preferences(body: MarkdownBody): path = data_dir / "data" / "preferences.md" path.parent.mkdir(parents=True, exist_ok=True) path.write_text(body.content, encoding="utf-8") return {"ok": True} ``` The same unauthenticated pattern is used for the research, report, and property APIs through line 143. ### Technical Analysis The dashboard stores and serves customer profile information that can include family composition, financial budget, workplace and commute, school-enrollment requirements, property ownership, preferred locations, and recommendation history. None of the API routes require a session, access token, API key, or other proof of authorization. The CORS policy allows every origin, HTTP method, and request header. As a result, arbitrary websites are explicitly authorized by the server to make cross-origin API requests. The default `127.0.0.1` binding limits direct network access, but it does not provide an authorization boundary against malicious browser pages targeting localhost. Browser Private Network Access controls may mitigate some environments, but they a ...[truncated 2281 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Require authentication for every `/api/*` route. For a local application, generate a cryptographically random token at startup and require it through an `Authorization` header. - Restrict CORS to the exact dashboard origin: ```python app.add_middleware( CORSMiddleware, allow_origins=["http://127.0.0.1:8000", "http://localhost:8000"], allow_methods=["GET", "PUT"], allow_headers=["Authorization", "Content-Type"], ) ``` - Validate the `Origin` and `Host` headers and reject unknown values to reduce DNS-rebinding and cross-origin localhost attacks. - Keep loopback binding as the default and require an explicit security warning or authentication configuration before permitting a non-loopback host. - Add CSRF protection if cookie-based authentication is introduced. - Apply request-size limits and Pydantic schemas to all write endpoints, including `/api/properties`. - Return only frontend configuration that must be public. Restrict the AMap key by approved domain, service type, and quota at the AMap provider. - Clearly document that the customer-profile files contain sensitive personal data and should not be exposed on shared systems. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:229
Finding
Third-Party Packages and Browser Binaries Are Installed Without Version or Integrity Pinning<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:229` **Additional Locations**: `SKILL.md:74`, `scripts/server.py:11`, `scripts/search_wechat.py:17` **Vulnerability Type**: Unpinned dependency installation **Risk Level**: Medium ### Vulnerable Code `SKILL.md` instructs the user to install frontend dependencies: ```bash cd webapp && npm install && npm run generate && cd - ``` It also instructs the user to install Playwright and a browser binary without pinning or integrity verification: ```text `--fetch-content` and `--url` depend on Playwright (`pip3 install playwright && python3 -m playwright install chromium`) ``` The server documentation similarly uses unpinned packages: ```python # Install dependencies (first use) pip install fastapi uvicorn ``` The search script repeats the unpinned Playwright installation instruction: ```python Dependencies (required only for --fetch-content): pip install playwright && python -m playwright install chromium ``` ### Technical Analysis The installation commands resolve whatever package versions are current at execution time. No audited lockfile, exact version constraint, package hash, or browser-binary checksum is enforced in the reviewed artifact. Package installation and browser provisioning are security-sensitive operations because package build hooks, installation scripts, imported modules, and downloaded browser binaries execute with the user's privileges. The external `webapp` project referenced by `npm install` is outside the supplied audit artifact, so its package manifest and lockfile could not be verified. There is no evidence that the named dependencies are malicious. The vulnerability is the absence of reproducible and integrity-verified dependency controls, which increases exposure to compromised releases, unexpected breaking changes, registry compromise, or modifications to the external web application. ### Attack Path 1. A user follows the installation instructions in `SKIL ...[truncated 1338 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin exact versions for all Python dependencies. - Generate a reviewed requirements lockfile containing cryptographic hashes and install with hash enforcement, for example: ```bash pip install --require-hashes -r requirements.lock ``` - Include and enforce an npm lockfile using: ```bash npm ci ``` instead of an unconstrained `npm install`. - Review and pin transitive dependencies, not only direct dependencies. - Pin the Playwright version and ensure that the associated Chromium revision is reproducible. - Use trusted package registries and disable unneeded alternate indexes. - Run installation and browser provisioning in a dedicated virtual environment or sandbox with minimal filesystem and network privileges. - Include the referenced `webapp` manifest and lockfile in the auditable project scope. - Add automated dependency scanning and a controlled update process rather than resolving new versions during ordinary Skill execution. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (31)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill includes instructions to scrape WeChat content via Sogou/Playwright, follow redirect links, persist fetched data locally, and use browser automation to obtain dynamically rendered content. That materially exceeds a simple advisory role and introduces web-scraping, content-ingestion, and local persistence risks, including ingestion of untrusted content, potential policy evasion behavior, and exposure to malicious pages or sensitive data capture during automated browsing.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill includes instructions to scrape WeChat content via Sogou/Playwright, follow redirect links, persist fetched data locally, and use browser automation to obtain dynamically rendered content. That materially exceeds a simple advisory role and introduces web-scraping, content-ingestion, and local persistence risks, including ingestion of untrusted content, potential policy evasion behavior, and exposure to malicious pages or sensitive data capture during automated browsing.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill includes instructions to scrape WeChat content via Sogou/Playwright, follow redirect links, persist fetched data locally, and use browser automation to obtain dynamically rendered content. That materially exceeds a simple advisory role and introduces web-scraping, content-ingestion, and local persistence risks, including ingestion of untrusted content, potential policy evasion behavior, and exposure to malicious pages or sensitive data capture during automated browsing.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill includes instructions to scrape WeChat content via Sogou/Playwright, follow redirect links, persist fetched data locally, and use browser automation to obtain dynamically rendered content. That materially exceeds a simple advisory role and introduces web-scraping, content-ingestion, and local persistence risks, including ingestion of untrusted content, potential policy evasion behavior, and exposure to malicious pages or sensitive data capture during automated browsing.

Credential Access

High
Category
Privilege Escalation
Content
│       ├── school_enrollment_policies.md ← 学区房与入学政策参考
│       └── map_display.md        ← 地图展示房源方案参考
└── .skills-data/zhongjie/        ← 运行时数据(已 gitignore)
    ├── .env
    └── data/
        ├── preferences.md        ← 客户画像与偏好记录
        ├── research.md           ← 调研资料
Confidence
91% confidence
Finding
The skill’s documented runtime layout explicitly references a `.env` file inside its working data area while also directing the agent to operate over the project root and start backend services. In a skill with file-read capability and no clear permission boundary, normalizing a secrets file within the accessible workspace creates a realistic risk of accidental secret disclosure, prompt-induced exfiltration, or unsafe use of credentials by other components.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
This file adds broad微信公众号搜索、URL解析、正文抓取和反自动化规避能力, which is unrelated to a房产买房参谋 skill. In-context, this expands the skill’s data-access and browsing surface beyond its stated purpose, enabling arbitrary content discovery and extraction from third-party sites and increasing the chance of unauthorized scraping, policy bypass, or covert capability misuse.

Credential Access

High
Category
Privilege Escalation
Content
管理运行时数据目录结构(遵循 .skills-data 规范):

    <project_root>/.skills-data/zhongjie/
        .env            — 环境变量配置
        data/           — 持久化数据(搜索结果等)
        cache/          — 可安全删除的缓存
        configs/        — 额外配置文件
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
管理运行时数据目录结构(遵循 .skills-data 规范):

    <project_root>/.skills-data/zhongjie/
        .env            — 环境变量配置
        data/           — 持久化数据(搜索结果等)
        cache/          — 可安全删除的缓存
        configs/        — 额外配置文件
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
管理运行时数据目录结构(遵循 .skills-data 规范):

    <project_root>/.skills-data/zhongjie/
        .env            — 环境变量配置
        data/           — 持久化数据(搜索结果等)
        cache/          — 可安全删除的缓存
        configs/        — 额外配置文件
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
LOGS_DIR = os.path.join(SKILL_DATA_DIR, "logs")
TMP_DIR = os.path.join(SKILL_DATA_DIR, "tmp")

ENV_FILE = os.path.join(SKILL_DATA_DIR, ".env")


def ensure_dirs():
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
LOGS_DIR = os.path.join(SKILL_DATA_DIR, "logs")
TMP_DIR = os.path.join(SKILL_DATA_DIR, "tmp")

ENV_FILE = os.path.join(SKILL_DATA_DIR, ".env")


def ensure_dirs():
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill instructs the agent to read and write local files, access environment-backed configuration, and use networked tooling, but it declares no explicit tool scope or permission boundaries. This increases the chance of unintended file access, overbroad network use, or misuse of sensitive runtime context because neither the platform nor the user is given a least-privilege contract.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
Line L292 explicitly requires '沟通全程使用中文', which forces a specific language choice for all interactions. The policy for this audit flags language or locale constraints unless the skill offers user choice or clearly documents a justified region-specific need.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
The manifest emphasizes advisory, search, comparison, and recommendation behavior for home-buying decisions. In the actual code, the app performs persistent write operations to backend endpoints such as `/api/preferences`, `/api/research`, and `/api/report` using PUT requests, which makes the skill an editor/content-management interface in addition to an advisor.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
Visible UI labels and guidance throughout the bundled file are exclusively in Chinese, such as navigation labels and configuration instructions, with no indication of language selection or opt-in. This creates a natural-language policy concern if the skill is expected to be locale-neutral, because users are implicitly forced into a specific language.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
The bundled markdown renderer is configured with html: true and its output is later rendered into the page, enabling persisted content to contain raw HTML. In this skill, profile/research/report content is fetched from and written back to backend endpoints, so any malicious HTML stored there can become a persistent XSS payload affecting later viewers.

Missing User Warnings

Medium
Confidence
99% confidence
Finding
Rendered markdown is assigned to innerHTML in multiple places (for both preview and saved content views) after being processed by a renderer that allows raw HTML. Because this content is persisted via backend APIs, an attacker can inject HTML/JS-bearing payloads that execute when any user opens the affected page, resulting in stored XSS.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The document explicitly instructs users to disclose their AMap API key and security code to the agent and store them in a local .env file, but provides no warning that these are sensitive credentials or guidance on limiting exposure. Even though these are third-party map credentials rather than highly privileged system secrets, normalizing credential sharing with the skill increases the risk of accidental leakage, misuse, or insecure storage.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
This code file contains natural-language descriptions, comments, output strings, and error text exclusively in Chinese, which effectively forces a specific language for users. The policy requires flagging language or locale constraints unless the skill offers user opt-in or clearly documents a justified region-specific limitation.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The code hard-codes the HTTP Accept-Language header to prefer zh-CN and zh, which imposes a specific language/locale choice rather than reflecting user preference. This matches the language/locale policy violation category because there is no user opt-in or documented justification for forcing Chinese.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The Playwright browser context is explicitly created with locale="zh-CN" and timezone_id="Asia/Shanghai", which forces a specific regional setting for all users. The file does not offer a user-selectable option or explain why this locale restriction is required.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
The /api/config endpoint returns AMap API values directly to any caller, and CORS is configured to allow any origin. Even if these are intended for browser use, exposing them without origin restrictions or a stronger justification increases the risk of unauthorized reuse, quota theft, and third-party abuse of the associated map account.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The PUT handlers for preferences, research, report, and properties persist incoming data to files under .skills-data, which can affect user data. Although the code performs these writes as part of the service behavior, this file does not include endpoint-level comments, prompts, or other user-facing disclosure that these requests will overwrite stored content.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
The stylesheet sets `font-family` on `html,body,#app` to include `PingFang SC`, `Hiragino Sans GB`, and `Microsoft YaHei`, which are Chinese locale-oriented fonts, as part of the primary UI font stack. This is natural-language or locale-related behavior that appears to impose a specific locale preference without any visible user choice or justification in this file.

Static analysis

Detected: suspicious.insecure_tls_verification, suspicious.obfuscated_code

HTTPS certificate verification is disabled.

Warn
Code
suspicious.insecure_tls_verification
Location
scripts/search_wechat.py:69

Potential obfuscated payload detected.

Warn
Code
suspicious.obfuscated_code
Location
assets/dist/assets/index-DrG3YEG2.js:2