Back to skill

Security audit

Beike Xiaoqu Research

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated real-estate research purpose, but it gives broad browser-control authority and contains unsafe script construction that could let crafted inputs execute local code.

Review before installing. Use a dedicated Chrome profile, choose a private output directory instead of shared /tmp paths, avoid running it on untrusted names or board strings until the Python interpolation bugs are fixed, and treat PAL consensus reports as advisory because scraped data and model prompts can be manipulated.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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/region_discover.sh:229
Finding

Arbitrary Python Code Execution Through Shell-to-Python String Interpolation

Content
View full analysis
/dev/null) ``` In `scripts/region_discover.sh:343-362`, a community name obtained from remote page content is inserted into another generated Python program: ```bash python3 -c " import json with open('$ALL_CANDIDATES_JSON') as f: data = json.load(f) for x in data: if x['name'] == '$name': x['xiaoqu_id'] = '$XID' x['detail_file'] = '${name}_xiaoqu.json' # 补充详情数据 try: with open('$DETAIL_DIR/${name}_xiaoqu.json') as f2: detail = json.load(f2) x['building_type'] = detail.get('building_type', '') x['total_units'] = detail.get('total_units', '') x['far'] = detail.get('far', '') x['green_rate'] = detail.get('green_rate', '') x['mgmt_company'] = detail.get('mgmt_company', '') x['mgmt_fee'] = detail.get('mgmt_fee', '') x['views_30d'] = detail.get('views_30d', '') except: pass break with open('$ALL_CANDIDATES_JSON', 'w') as f: json.dump(data, f, ensure_ascii=False, indent=2) " 2>/dev/null ``` In `scripts/fetch_xiaoqu.sh:205-213`, user-controlled `NAME` and `OUTD ...[truncated 3713 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Warning
Location
scripts/consensus_analyze.py:91
Finding

Indirect Prompt Injection Through Untrusted Candidate Data and Model Responses

Content
View full analysis
str: """将候选小区列表构建为结构化文本摘要""" lines = [ f"# 上海二手房候选小区数据(贝壳找房,{datetime.now().strftime('%Y-%m-%d')} 抓取)", "", f"## 购房需求", requirements, "", f"## 候选小区清单(共 {len(candidates)} 个,按流动性排序)", "", "| 序号 | 小区名 | 板块 | 均价(万/㎡) | 建年 | 总户数 | 在售 | 90天成交 | 地铁 | 建筑 | 容积率 | 物业 |", "|------|--------|------|------------|------|-------|------|---------|------|------|--------|------|", ] for i, r in enumerate(candidates[:20], 1): # 最多20个 price = int(r.get('price', 0) or 0) est_130 = round(price * 130 / 10000) if price else '?' metro = r.get('metro', '')[:15] or '无' lines.append( f"| {i} | {r.get('name','')} | {r.get('board','')} | {price/10000:.1f} " f"| {r.get('year','')} | {r.get('total_units','')} " f"| {r.get('on_sale','')} | {r.get('sold_90d','')} " f"| {metro} | {r.get('building_type','')} " f"| {r.get('far','')} | {r.get('mgmt_company','')[:8]} |" ) ``` The resulting summary is inserted directly into the first two model prompts: ```python summary = build_summary(candidates, requirements) results = {} print(f"\n📤 向模型1 ({model1}) 发送稳健视角评估...") resp1 = call_pal_chat( prompt=PROMPT_TEMPLATE_MODEL1.format(summary=summary), model=model1, workdir=workdir, thinking_mode='high', ) ``` The first-stage model responses are then inserted verbatim into a third model prompt: ```python opinion1 = resp1.get('content', '(模型1无响应)') opinion2 = resp2.get('content', '( ...[truncated 3329 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (22)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

描述包含两类核心能力,其中代码只覆盖了第一类的一部分:面向单个小区的数据抓取与解析。它确实使用 mcp-chrome 抓取贝壳页面,并获取详情、在售、成交数据,和“单小区深度研究”基本一致。但代码没有任何按地区批量发现小区、筛选候选清单的逻辑,也没有调用 PAL MCP、mcporter 或任何多模型 consensus 评估流程。因此,声明把技能说得比实际代码更广,属于能力描述与实际行为不符。验证码处理、Tab 选择、输出摘要等属于实现细节,不构成额外未声明风险;主要问题是缺少声明中的第二模式和多模型评估能力。

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/region_discover.sh (reported line 73)May include surrounding context.

sh
# ── 工具函数 ──────────────────────────────────────────────────────────────
mcp_call() {
  curl -s -X POST "http://127.0.0.1:12306/mcp" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json, text/event-stream" \
    -H "mcp-session-id: $SESSION_ID" \

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill clearly instructs use of shell commands and writes scraped results to local directories such as /tmp/beike and /tmp/result, but it does not declare any tool scope or permissions boundary. That creates an overbroad execution surface where an agent may invoke shell and file-write capabilities without explicit user-visible constraints, increasing the risk of unintended command execution or data persistence.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill describes generated output files but does not prominently warn users that it will scrape real-estate data and persist multiple JSON/CSV artifacts to local storage paths. Lack of disclosure increases privacy and operational risk because users or calling agents may not realize data is being retained on disk, possibly in shared or insecure temporary directories.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger examples include broad natural-language phrases like '查XX小区的信息' and '帮我发现候选小区', which could match ordinary user requests and cause accidental invocation of a web-scraping, file-writing skill. In agent environments, overbroad triggering can lead to unintended browsing, scraping, local data creation, and calls to connected services without sufficiently explicit user intent.

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

1. mcp-chrome 连接

bash
curl -s http://127.0.0.1:12306/mcp -X POST \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"agent","version":"1.0"}}}' \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The document explicitly states that the browser can be controlled through the user's already logged-in Chrome session, but it does not provide a prominent warning about access to authenticated data, account actions, or privacy exposure. In this skill context, that omission is more dangerous because the entire workflow depends on automating a live browser session against a real estate site and could expose cookies, personal browsing context, saved sessions, or trigger unintended account-bound actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The examples demonstrate navigation, arbitrary JavaScript execution, element clicking, tab switching, and screenshots, but they lack a consolidated warning that these actions can read page contents, capture sensitive information, modify session state, and write files locally. In this skill, those examples are operational guidance, so a user or agent following them could directly access private page data or create local artifacts without understanding the security implications.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/consensus_analyze.py (reported line 57)May include surrounding context.

python
cmd = ['mcporter', 'call', 'pal.chat', '--args', args_json, '--output', 'json']

    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
        output = result.stdout.strip()
        if not output:
            return {'error': result.stderr[:500], 'content': ''}

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script sends candidate housing data and user requirements to external PAL models without any explicit notice, consent gate, or data minimization. Even if the data is not highly sensitive in all cases, requirements and location preferences can reveal personal financial constraints and housing intent, and the skill context increases exposure because the entire candidate summary is forwarded to third-party services.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The generated report states that data came from 'mcp-chrome 实时抓取', but this script actually reads a local JSON file and performs model analysis. That provenance mismatch can mislead users about freshness and source authenticity, causing bad decisions based on stale, tampered, or indirectly sourced data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script's usage text, prompts, status messages, and summaries are entirely in Chinese, which imposes a specific language on users without any opt-in or documented locale constraint. This matches the policy category for language or locale restrictions lacking user choice.

Content

No source excerpt is available for this finding.

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

md
# ── 1. 初始化 mcp-chrome session ──────────────────────────────────────────
echo "🔌 连接 mcp-chrome..."
INIT_RESP=$(curl -s -i -X POST "http://127.0.0.1:12306/mcp" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"beike-fetch","version":"1.0"}}}')

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/fetch_xiaoqu.sh (reported line 28)May include surrounding context.

sh
# ── 1. 初始化 mcp-chrome session ──────────────────────────────────────────
echo "🔌 连接 mcp-chrome..."
INIT_RESP=$(curl -s -i -X POST "http://127.0.0.1:12306/mcp" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"beike-fetch","version":"1.0"}}}')

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/region_discover.sh (reported line 59)May include surrounding context.

sh
# ── 1. 初始化 mcp-chrome session ──────────────────────────────────────────
echo "🔌 连接 mcp-chrome..."
INIT_RESP=$(curl -s -i -X POST "http://127.0.0.1:12306/mcp" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"beike-fetch","version":"1.0"}}}')

External Transmission

Medium
Category
Data Exfiltration
Confidence
74% confidence
Finding

The helper forwards arbitrary tool names and JSON arguments to a privileged local MCP browser-control service using the acquired session ID, effectively treating the localhost service as fully trusted. If a malicious or unexpected process is listening on 127.0.0.1:12306, or if this script is adapted with tainted inputs, it could drive the user's browser, read page contents, and access authenticated browsing context without additional verification.

Content

Scanner excerpt · scripts/fetch_xiaoqu.sh (reported line 43)May include surrounding context.

sh
# ── 工具函数 ──────────────────────────────────────────────────────────────
mcp_call() {
  local id=$1 tool=$2 args=$3
  curl -s -X POST "http://127.0.0.1:12306/mcp" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json, text/event-stream" \
    -H "mcp-session-id: $SESSION_ID" \

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This shell script embeds its usage instructions, parameter descriptions, examples, and operational messages entirely in Chinese. Under the policy, forcing a specific language without offering the user a language or locale choice is a natural-language policy violation.

Content

No source excerpt is available for this finding.

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 · references/mcp-chrome-api.md (reported line 18)May include surrounding context.

md
# ── 工具函数 ──────────────────────────────────────────────────────────────
mcp_call() {
  curl -s -X POST "http://127.0.0.1:12306/mcp" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json, text/event-stream" \
    -H "mcp-session-id: $SESSION_ID" \

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/region_discover.sh (reported line 73)May include surrounding context.

sh
# ── 工具函数 ──────────────────────────────────────────────────────────────
mcp_call() {
  curl -s -X POST "http://127.0.0.1:12306/mcp" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json, text/event-stream" \
    -H "mcp-session-id: $SESSION_ID" \

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

Natural-language instructions, prompts, CLI descriptions, logs, and generated report text are all hard-coded in Chinese, and the skill does not provide any opt-in or language-selection mechanism. Under the stated policy, forcing a specific language without user choice can be a locale-policy violation unless the restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script creates an output directory and later saves fetched page text and parsed JSON files containing property-related query results under /tmp or a user-specified path. While it prints save locations after writing, there is no prior warning in comments or usage text that running the script will persist collected data to disk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This file includes natural-language usage text and runtime messages exclusively in Chinese, which can force a specific language experience on users without opt-in. The stated policy requires flagging language or locale constraints unless the skill offers a choice or clearly documents a justified region-specific limitation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.