Back to skill

Security audit

Tradingagents Cn Skill

Security checks for vulnerabilities and agentic risk

Overview

The stock-report skill is mostly purpose-aligned, but its normal workflow includes unsafe command, file-write, and PDF-rendering patterns that need review before installation.

Review before installing. Use only in an isolated workspace with limited filesystem and network access until command construction, stock-code validation, path containment, HTML escaping, renderer network restrictions, and log minimization are fixed. Do not feed sensitive account screenshots or private trading information unless you accept that report and log files may be written locally.

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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:23
Finding

Shell Command Injection Through Interpolated LLM Output and Stock Codes

Content
View full analysis
' | python3 {baseDir}/scripts/validate_step.py --step <步骤名> --stock-code <股票代码> --attempt <次数> ``` The logging setup also places a stock code in a shell command: ```bash export TRADINGAGENTS_LOG_FILE="{baseDir}/scripts/logs/{股票代码}_{YYYYMMDD}_{HHMMSS}.log" mkdir -p {baseDir}/scripts/logs ``` Equivalent raw-output interpolation is specified repeatedly, including: ```bash echo '' | python3 {baseDir}/scripts/validate_step.py --step bull_analyst --stock-code {股票代码} --attempt 1 ``` ### Technical Analysis The workflow instructs the Agent to insert raw LLM output directly into a single-quoted shell argument. Single quotes appearing in model output terminate the intended argument. The remaining text is then interpreted as shell syntax. LLM output is not a trusted boundary. It can be influenced by: - Direct user-supplied text. - OCR content from attacker-controlled images. - Search-result titles and snippets. - Prompt injection contained in external content. - Previous analysis-stage output. The stock code is also inserted into shell commands. In the double-quoted `export` command, shell substitutions such as `$(command)` remain active. Therefore, treating the stock code as a benign identifier is insufficient. The Python validator itself safely reads standard input, so no shell interpolation is necessary. The vulnerability is introduced by the Skill's prescribed invocation method. ### Attack Path 1. An attacker supplies a stock description, stock code, OCR image, or external text that influences an LLM response. 2. The generated response includes a single quote followed by shell syntax, for example a sequence concep ...[truncated 1408 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/pdf_generator.py:147
Finding

Unescaped HTML Injection and Server-Side Resource Fetching During PDF Generation

Content
View full analysis
0: for news in news_analyst["news_list"]: sentiment_color = "#2e7d32" if "多" in news.get("sentiment", "") or "正" in news.get("sentiment", "") else ("#c62828" if "空" in news.get("sentiment", "") or "负" in news.get("sentiment", "") else "#666") # 摘要 fallback:summary > snippet > title summary_text = (news.get('summary') or '').strip() if not summary_text: summary_text = (news.get('snippet') or '').strip() if not summary_text: summary_text = news.get('title', '暂无摘要') news_list_html += f"""
{news.get('title', '')} {news.get('sentiment', '')}
{news.get('date', '')} {news.get('source', '')}
{summary_text}
{f'' if news.get("url") else ""}
""" ``` The completed HTML is passed directly to the PDF renderer: ```python try: from weasyprint import HTML HTML(string=html_content).write_pdf(output_path) return ``` The fallback renderer also processes the same attacker-influenced HTML: ```python subprocess.run( [' ...[truncated 2980 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/pdf_generator.py:44
Finding

Path Traversal Through Unsanitized Stock Code in Report Filename

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/validate_step.py:302
Finding

Attacker-Influenced Log Paths Permit Writes Outside the Log Directory

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/validate_step.py:242
Finding

Unreachable Conditional Validation Allows Unsafe and Malformed Trading Data

Content
View full analysis
Tuple[bool, Optional[str]]: """ 验证必填字段。 返回 (is_valid, missing_field_or_None) 特殊条件逻辑: - trader 步骤:buy_price/target_price/stop_loss 仅在 decision="买入" 时必填 """ required = REQUIRED_FIELDS.get(step, []) for field in required: if field == "trader": # trader 步骤的条件必填逻辑 decision = data.get("decision", "") if decision == "买入": for pf in ["buy_price", "target_price", "stop_loss"]: v = data.get(pf) if v is None or v == "": return False, pf # 买入时 also validate position_size ps = data.get("position_size", "") if not ps or ps == "": return False, "position_size" else: # 持有/观望:只要求 decision 和 position_size(非null) if not data.get("position_size") or data.get("position_size") == "": return False, "position_size" # buy_price/target_price/stop_loss 允许为 null(但 reference_* 应有值) elif "." in field: # 嵌套字段 parts = field.split(".") value = data for part in parts: if not isinstance(value, dict) or part not in value: return False, field value = value[part] if value is None or value == "" or (isinstance(value, list) and len(value) == 0): return False, field else: if field not in data or data[field] is None or data[field] == "": return False, field return True, None ``` The trader requirements are configured as: ```python "trader": ["decision", "position_size"], ``` ...[truncated 2087 chars]
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (28)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个面向用户的完整股票多智能体分析与报告生成技能,而提供的代码块仅是后台辅助脚本 validate_step.py,用于校验各分析步骤的LLM输出格式与字段完整性,并记录日志。它确实提到了 bull_analyst、bear_analyst、manager、trader、risk_manager 等步骤,说明它可能服务于该更大系统,但这段代码本身并不执行股票分析、不生成买卖建议、不进行多空辩论内容生成,也不生成PDF。因此该代码块的实际主要用途与声明的主要用途存在显著不一致,应判定为 mismatch。

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill instructs the agent to send user-provided screenshots/text to OCR, LLM, and web-search services, and to persist logs and PDF reports on disk, but it does not disclose this to the user up front. This creates a real privacy and data-governance risk, especially because screenshots may contain sensitive financial information, account details, or proprietary trading context that users may not expect to be stored or transmitted.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README explicitly states that every step's input, output, and validation result are logged to files, but provides no warning, minimization guidance, or handling requirements for potentially sensitive data. In this skill's context, user prompts may include trading ideas, screenshots, pasted code, or other proprietary information, so broad logging can create unintended persistence and disclosure risk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill invokes shell commands, sets environment variables, writes logs/reports to disk, and runs local Python scripts, but it declares no explicit tool scope or permission boundaries. That increases the blast radius if the skill is invoked unexpectedly or if downstream inputs are attacker-controlled, because the agent may perform file/system actions without transparent least-privilege constraints.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger conditions are extremely broad and overlap with ordinary investing, screenshot, code-analysis, and advice requests, which can cause the skill to activate in situations the user did not clearly intend. In this skill, activation leads to external searches, OCR/LLM processing, local logging, and file generation, so overbroad invocation can expose user content and trigger unnecessary actions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The language requirements state that all system prompts, user messages, and analysis outputs must be in Chinese. This is a language policy constraint expressed in natural language, and the file does not offer opt-in, fallback, or a documented justification that the skill is intentionally region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The prompt explicitly requires output in Chinese via the language requirements section. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is clearly justified, which is not present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The language requirements explicitly mandate Chinese output ('使用中文输出') and do not provide any user opt-in, fallback, or explanation that the skill is region-specific. This matches the policy concern for language/locale constraints imposed unconditionally in natural-language instructions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Lines L86-L89 explicitly require the model to use Chinese output, and earlier lines also require Chinese key names. Under the policy, forcing a specific language without user opt-in is a natural-language locale violation unless the restriction is clearly justified as region-specific, which is not present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The file title and all operative instructions are written in Chinese, and the template implicitly requires output in Chinese. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Lines L56-L58 impose a fixed language requirement ('使用中文输出') as a hard constraint. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the restriction is explicitly justified as region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The prompt gives concrete position sizing, drawdown tolerance, profit targets, and risk/reward ratios that can directly influence real financial decisions, yet it contains no warning that the output is informational only and not personalized financial advice. In the context of a stock-analysis skill explicitly triggered by requests for buy/sell suggestions and investment reports, this increases the chance users will over-rely on the model's recommendations and suffer financial harm.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The entire prompt is written to require operation in Chinese and provides no indication that the user can choose another language or locale. Under the policy, a fixed language requirement without user opt-in is a natural-language policy violation unless the locale constraint is explicitly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The language requirements explicitly require responses in Chinese only. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is justified, which is not provided here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The language requirements explicitly require output in Chinese and standard technical-analysis terminology. This is a natural-language policy concern because it forces a specific language without user opt-in or any documented region-specific justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The entire skill is written as a fixed Chinese-language prompt and output schema, including decision labels and narrative fields, with no indication that the user can choose another language. This is a natural-language locale constraint and the file does not document any region-specific justification or opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file’s natural-language descriptions and generated report content are explicitly in Chinese, including the HTML locale declaration and all report labels, but there is no mechanism for user language selection or documented justification for enforcing this locale. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code creates a reports directory and later writes generated report content to local files, including the final PDF and a fallback HTML file. Although the behavior is documented in developer-oriented docstrings, there is no user-facing disclosure, confirmation prompt, or visible warning in the generation path itself before persisting analysis data to disk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The HTML template sets lang="zh-CN", reinforcing that the generated report is fixed to Simplified Chinese. Because the file does not provide any user language choice or explicit documented justification for a mandatory Chinese locale, this conflicts with the language/locale policy rule.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest describes a stock analysis and PDF report generation skill, but this implementation falls back to invoking the external wkhtmltopdf executable through subprocess.run. Spawning external processes is a broader execution capability than is normally implied by a stock-report skill and is not declared in the manifest description.

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

python
f.write(html_content)
                temp_html = f.name

            subprocess.run(
                ['wkhtmltopdf', '--page-size', 'A4', '--margin-top', '15mm',
                 '--margin-bottom', '15mm', '--margin-left', '12mm', '--margin-right', '12mm',
                 temp_html, str(output_path)],

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The fallback PDF conversion path invokes an external executable via subprocess, which is a safety-relevant operation under the rule. The code contains no confirmation, visible notice, or warning to the user that an external system tool will be executed during report generation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

On validation failure, the script writes the first 500 characters of raw LLM output to a persistent log file. In this skill, LLM outputs can contain user-provided stock screenshots, extracted text, trading rationale, API-returned content, or other sensitive material, so failed generations may leak private or proprietary data to disk without notice or consent. The risk is increased because failure paths often contain the least-sanitized content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

On successful validation, the script logs the cleaned validated JSON output to disk, which may still include sensitive or regulated content derived from user input or external data sources. Because this is a stock-analysis skill that processes financial prompts and potentially uploaded screenshots/code, persistent logging expands the data exposure surface and may leak recommendations, investment context, or confidential inputs to anyone with filesystem access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The README advertises generation of a professional PDF report without warning that analysis content will be persisted to a file. Because this skill is designed to process investment analysis inputs and possibly user-provided screenshots or text, silent file creation can leave sensitive or regulated content on disk where users may not expect it.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.