Back to skill

Security audit

科技投资日报

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent report-and-Feishu workflow, but it uses central Feishu credentials and sends PDFs to a fixed recipient without adequate user control.

Review this skill before installing. It should only be used in an environment where sending technology investment reports to the hardcoded Feishu recipient is intended, and where the Feishu app credentials in /root/.openclaw/openclaw.json are safe for agent-executed code to access. Prefer a version that uses platform-managed messaging, asks the user to confirm the recipient before every send, uses HTTPS/authenticated market data, and sandboxes PDF rendering.

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)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:69
Finding

Direct Access to Central Feishu Credentials and Hard-Coded Report Recipient

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/report.py:10
Finding

Stock Quotes Retrieved Over Unauthenticated Plaintext HTTP

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_report.py:61
Finding

Report Generator Uses Plaintext HTTP for Financial Market Data

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/to_pdf.py:6
Finding

Unrestricted Resource Resolution During Markdown-to-PDF Conversion

Content
View full analysis
@font-face {{ font-family: 'NotoSans'; src: url('/tmp/NotoSansCJK.ttf'); }} body {{ font-family: 'NotoSans', sans-serif; font-size: 11pt; color: #222; }} h1 {{ font-size: 18pt; color: #1f497d; border-bottom: 2px solid #1f497d; padding-bottom: 4px; }} h2 {{ font-size: 14pt; color: #1f497d; margin-top: 16px; }} h3 {{ font-size: 12pt; color: #333; }} table {{ border-collapse: collapse; width: 100%; margin: 10px 0; }} th {{ background: #4472c4; color: white; padding: 6px 8px; border: 1px solid #ccc; }} td {{ padding: 5px 8px; border: 1px solid #ccc; }} tr:nth-child(even) td {{ background: #eef2ff; }} hr {{ border: none; border-top: 1px solid #ccc; margin: 12px 0; }} p {{ margin: 6px 0; line-height: 1.6; }} ul {{ margin: 4px 0; padding-left: 20px; }} li {{ margin: 3px 0; }} {html_body}""" HTML(string=html).write_pdf(output_path, stylesheets=[CSS(string='@page { margin: 1.5cm; }')]) return output_path ``` ### Technical Analysis The converter accepts arbitrary Markdown from standard input, converts it to HTML, and passes the result to WeasyPrint without defining a restrictive URL fetcher. Markdown can contain images, links, or raw HTML that reference external URLs or local resources. During PDF generation, the renderer may attempt to resolve those resources from the host running the Skill. This creates a server-side request forgery and unintended local-resource access surface when the Markdown is attacker-controlled or incorporates untrusted external content. Retrieved content may also be embedded in the generated PDF. T ...[truncated 1849 chars]
Remediation
View remediation
Vulnerability Patterns
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

代码与声明在核心主题上部分一致:确实抓取财联社新闻、提取部分上市公司并获取股价、生成日报文本。但声明描述了完整的“生成与推送”流程,包括通过飞书发送完整Markdown报告、生成PDF附件,以及支持cron定时任务;这些能力在提供的代码中均未体现。代码只是一个本地生成报告并输出到stdout的脚本,没有任何飞书API调用、文件导出/PDF转换、消息发送、任务调度入口或定时器配置。此外,所谓“深度分析报告”在实现上仅是新闻筛选加股价表格,缺少分析逻辑。因此描述明显高于实际行为,属于描述与代码行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

声明描述的是一个完整的“科技行业投资日报生成与推送”技能,核心能力包括新闻抓取、股价获取、分析报告生成、飞书推送和PDF附件生成。而提供的代码片段只是一个辅助脚本,功能范围明显更窄:查询股票价格和将现成 Markdown 转成 PDF。虽然其中“获取股价”和“生成PDF附件”与声明部分吻合,但缺失了声明中的主要业务流程与对外推送能力,因此代码实际行为不能充分代表所宣称的技能用途,属于明显不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a full end-to-end tech investment daily report workflow: data collection, market/stock retrieval, report generation, Feishu delivery, and PDF attachment creation. The supplied code chunk implements only the PDF-generation portion by converting provided Markdown into a PDF file. PDF creation is consistent with one supporting detail in the description, but the chunk’s actual primary behavior is much narrower than the declared purpose and lacks the main advertised capabilities. Therefore, the description does not accurately represent what this specific code chunk actually does.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill invokes shell/Python/bash capabilities but does not declare any tool scope or allowed-tools restrictions. That makes the skill harder to sandbox and review, and increases the chance that powerful execution paths are available without explicit user or platform awareness.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest description and required report template are entirely specified in Chinese and require a Chinese-formatted日报 output, but do not state that this is optional or limited to a China-specific deployment context. That creates a language/locale policy concern because the skill appears to enforce a single language without user opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill silently transmits generated reports and PDF attachments to a fixed Feishu recipient without prominently warning the user in the description or runtime flow. Because reports may include sensitive analysis or user-supplied content, undisclosed outbound delivery materially increases data leakage risk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs reading Feishu app credentials directly from a local config file and then using them to call external APIs, despite already having a safer platform message action available. This expands the secret exposure surface and enables unauthorized use of tenant credentials for outbound messaging and file upload.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

This duplicate finding points to the same authentication request that exchanges local credentials for a Feishu tenant access token. While token retrieval alone is not the final leak, in this skill it is an enabling step for unauthorized outbound file and message operations.

Content

Scanner excerpt · SKILL.md (reported line 89)May include surrounding context.

md
user_id = "ou_159cbb6a3791ff5a98f3a2a4b38e7d4c"
pdf_path = "/tmp/tech-invest-YYYYMMDD.pdf"

token = requests.post(
    "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
    json={"app_id": app_id, "app_secret": app_secret}
).json()["tenant_access_token"]

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

This duplicate finding points to the same authentication request that exchanges local credentials for a Feishu tenant access token. While token retrieval alone is not the final leak, in this skill it is an enabling step for unauthorized outbound file and message operations.

Content

Scanner excerpt · SKILL.md (reported line 89)May include surrounding context.

md
user_id = "ou_159cbb6a3791ff5a98f3a2a4b38e7d4c"
pdf_path = "/tmp/tech-invest-YYYYMMDD.pdf"

token = requests.post(
    "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
    json={"app_id": app_id, "app_secret": app_secret}
).json()["tenant_access_token"]

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

This step uploads a local PDF file to Feishu, creating direct external transmission of generated content. Because the file originates from local temporary storage and may contain sensitive user or system-derived information, the upload is a concrete data exfiltration vector.

Content

Scanner excerpt · SKILL.md (reported line 95)May include surrounding context.

md
).json()["tenant_access_token"]

with open(pdf_path, "rb") as f:
    file_key = requests.post(
        "https://open.feishu.cn/open-apis/im/v1/files",
        headers={"Authorization": f"Bearer {token}"},
        data={"file_type": "pdf", "file_name": Path(pdf_path).name},

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

This duplicate finding identifies the message-send API call carrying the uploaded file to an external recipient. Given the hardcoded receive_id and absence of user-visible warnings, this is a real confidentiality risk rather than a harmless integration detail.

Content

Scanner excerpt · SKILL.md (reported line 102)May include surrounding context.

md
files={"file": f}
    ).json()["data"]["file_key"]

requests.post(
    "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id",
    headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
    json={"receive_id": user_id, "msg_type": "file", "content": json.dumps({"file_key": file_key})}

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

This duplicate finding identifies the message-send API call carrying the uploaded file to an external recipient. Given the hardcoded receive_id and absence of user-visible warnings, this is a real confidentiality risk rather than a harmless integration detail.

Content

Scanner excerpt · SKILL.md (reported line 102)May include surrounding context.

md
files={"file": f}
    ).json()["data"]["file_key"]

requests.post(
    "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id",
    headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
    json={"receive_id": user_id, "msg_type": "file", "content": json.dumps({"file_key": file_key})}

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code contains natural-language docstrings and user-facing status messages entirely in Chinese, starting with the module docstring and continuing through function descriptions and console output. Because the script provides no language selection, opt-in, or documented region-specific justification, it violates the language/locale policy criteria for forced language use.

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/generate_report.py (reported line 7)May include surrounding context.

python
from datetime import datetime

def fetch_url(url):
    result = subprocess.run(
        ['curl', '-s', '-L', '--max-time', '10', url],
        capture_output=True
    )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
80% confidence
Finding

The script fetches stock data over plain HTTP, so responses can be modified by a man-in-the-middle or malicious network intermediary. Because the fetched values are inserted directly into the generated investment report, an attacker could tamper with prices or symbols and cause false financial analysis or misleading outbound messages.

Content

Scanner excerpt · scripts/generate_report.py (reported line 60)May include surrounding context.

python
if not codes:
        return {}
    query = ','.join(codes)
    raw = subprocess.run(
        ['curl', '-s', f'http://qt.gtimg.cn/q={query}'],
        capture_output=True
    ).stdout.decode('gbk', errors='ignore')

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/report.py (reported line 10)May include surrounding context.

python
if not codes:
        return {}
    query = ','.join(codes)
    raw = subprocess.run(
        ['curl', '-s', f'http://qt.gtimg.cn/q={query}'],
        capture_output=True
    ).stdout.decode('gbk', errors='ignore')

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script silently makes an outbound network request to fetch market data without any user-facing disclosure or consent mechanism. In the context of an agent skill that auto-generates and pushes investment reports, this hidden egress can expose usage patterns and create trust, compliance, and data provenance issues, especially because it uses plain HTTP and an external subprocess.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The Markdown-to-PDF path silently executes external binaries to transform user-controlled content into a PDF. In this skill's context, reports are auto-generated and pushed to Feishu, so undisclosed execution of external converters increases attack surface and may surprise operators who do not expect local tool execution or potential file/network access by rendering engines.

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/report.py (reported line 34)May include surrounding context.

python
try:
        for engine in [['pandoc', md_path, '-o', output_path, '--pdf-engine=weasyprint'],
                       ['pandoc', md_path, '-o', output_path]]:
            r = subprocess.run(engine, capture_output=True)
            if r.returncode == 0:
                return output_path
        return None

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The natural-language description and usage guidance are written only in Chinese, which imposes a specific language context without offering a choice or documenting that the skill is intentionally Chinese-only. Under the policy, locale or language constraints should be optional or clearly justified.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.