Back to skill

Security audit

investment-tracker-app

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent investment-tracking purpose, but its setup and runtime instructions create review-level risks around unreviewed code, exposed financial APIs, and unsafe command examples.

Install only if you trust the external backend repository and are comfortable handling sensitive portfolio data. Run the backend on 127.0.0.1 or behind authentication/firewall controls, avoid exposing port 8000 to a network, use a pinned reviewed backend version, redact brokerage screenshots before AI analysis when possible, and carefully confirm any operation that replaces, rolls back, deletes, or resets investment records.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:69
Finding

Shell Command Injection Through Unescaped Dynamic Data

Content
View full analysis
' > /tmp/holdings_update.json curl -sS -X POST http://localhost:8000/api/holdings/bulk \ -H "Content-Type: application/json" \ -d "{\"holdings\": $(cat /tmp/holdings_update.json), \"label\": \" screenshot import\"}" rm /tmp/holdings_update.json ``` The same unsafe construction pattern is used for diary data: ```bash curl -sS -X POST http://localhost:8000/api/diary \ -H "Content-Type: application/json" \ -d "{\"date\": \"\", \"type\": \"\", \"code\": \"\", \"remark\": \"\", \"mood\": \"\"}" ``` ### Technical Analysis The instructions direct the agent to insert AI-generated analysis results and user-provided values directly into shell commands. These values cross two independent parsing boundaries: 1. The shell parses quoting, command substitution, redirection, and metacharacters. 2. The server subsequently parses the resulting text as JSON. JSON escaping does not make a value safe for interpolation into a shell command. In particular: - A single quote in the analyzed holdings data can terminate the quoted `echo` argument. - Double quotes, backticks, `$()`, semicolons, redirection operators, or newline characters in dynamically substituted values can change the command structure. - Diary remarks, labels, stock names, screenshot-derived values, and supplemental notes may originate from untrusted users or AI recognition output. - AI output must not be treated as trusted merely because it is expected to be JSON. The documented confirmation step does not prevent exploitation because users may confirm a legitimate-looking preview without seeing the shell rep ...[truncated 1296 chars]
Remediation
View remediation
'` to serialize untrusted content. 6. Validate the complete data schema before submission, including types, lengths, numeric ranges, stock-code formats, and permitted diary values. 7. Treat screenshot-recognition output as untrusted input. 8. Present the exact structured request body for confirmation rather than a simplified rendering. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:69
Finding

Predictable Shared Temporary File Enables Symlink and Race Attacks

Content
View full analysis
' > /tmp/holdings_update.json curl -sS -X POST http://localhost:8000/api/holdings/bulk \ -H "Content-Type: application/json" \ -d "{\"holdings\": $(cat /tmp/holdings_update.json), \"label\": \" screenshot import\"}" rm /tmp/holdings_update.json ``` ### Technical Analysis The workflow uses the fixed, globally predictable path `/tmp/holdings_update.json`. It does not: - Create the file exclusively. - Verify file ownership. - reject symbolic links. - Restrict permissions explicitly. - Ensure that the same file remains in place between writing and reading. - Prevent another process from replacing the path before deletion. On multi-user systems, `/tmp` is generally writable by other local users. Although sticky-directory protections restrict deletion of files owned by other users, they do not make predictable file creation safe. An attacker can create the path before the workflow runs, potentially as a symbolic link to another file writable by the victim. A time-of-check/time-of-use race also exists because writing, reading, and deleting are separate operations. ### Attack Path 1. A local attacker predicts that the skill will use `/tmp/holdings_update.json`. 2. Before execution, the attacker creates that path as a symbolic link to a file writable by the agent, or arranges to replace the path during the workflow. 3. The `echo ... >` redirection follows the symbolic link and overwrites the selected target. 4. Alternatively, the attacker replaces the temporary file after it is written but before `cat` reads it. 5. The modified content is submitted to `/api/holdings/bulk`, replacing the user's holdings with attacker-selected data. 6. The final `rm` may remove an attacker-controlled path entry, further complicating detection or recover ...[truncated 518 chars]
Remediation
View remediation

T03 · Remote Payload Retrieval and Execution

Warning
Location
README.md:7
Finding

Unpinned External Backend and Dependencies Are Retrieved and Executed Outside the Audited Artifact

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
README.md:110
Finding

Sensitive Financial API Is Bound to All Interfaces Without Documented Authentication

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (22)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · README.md (reported line 192)May include surrounding context.

md
> 所有数据存储在 `backend/investment.db`(SQLite 本地文件)。该文件不会被提交到 Git,请自行备份。删除此文件等同于清空所有数据。

**危险操作:`/api/reset`**
> `DELETE /api/reset?confirm=true` 会不可恢复地清除数据库中的所有持仓、日志、曲线和现金数据,请勿误操作。

**Python 虚拟环境位置**
> 一键启动脚本会将虚拟环境创建在项目目录的**上一级**(`../.venv/`),而非项目内部,避免被 Vite / TypeScript 扫描到。

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

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

md
| 类型 | 接口 | 执行前是否需要用户确认 |
|------|------|----------------------|
| **只读** | GET /api/holdings、GET /api/cash、GET /api/diary、GET /api/curve、GET /api/imports、GET /api/hs300 | **否**,直接执行并展示结果 |
| **写操作** | POST /api/holdings/bulk、POST /api/cash、POST /api/diary、POST /api/curve/point、POST /api/imports/rollback/{id}、DELETE /api/imports/{id} | **是**,必须先展示预览,等用户回复"确认"后再执行 |
| **分析+写** | POST /api/external/upload → POST /api/holdings/bulk | 分析步骤自动执行;写入步骤需用户确认 |

### 通用错误处理

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/api-docs.md (reported line 211)May include surrounding context.

md
| 类型 | 接口 | 执行前是否需要用户确认 |
|------|------|----------------------|
| **只读** | GET /api/holdings、GET /api/cash、GET /api/diary、GET /api/curve、GET /api/imports、GET /api/hs300 | **否**,直接执行并展示结果 |
| **写操作** | POST /api/holdings/bulk、POST /api/cash、POST /api/diary、POST /api/curve/point、POST /api/imports/rollback/{id}、DELETE /api/imports/{id} | **是**,必须先展示预览,等用户回复"确认"后再执行 |
| **分析+写** | POST /api/external/upload → POST /api/holdings/bulk | 分析步骤自动执行;写入步骤需用户确认 |

### 通用错误处理

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 99)May include surrounding context.

md
| curl 错误 / HTTP 状态码 | AI 应对策略 |
|------------------------|------------|
| `curl: (7) Connection refused` | 提示用户:"本地服务未启动,请在 backend 目录运行 `uvicorn main:app --reload --port 8000`" |
| `503` | 提示用户:"DASHSCOPE_API_KEY 未配置或无效,请检查 backend/.env 文件" |
| `502` | 提示用户:"AI 接口调用失败,请稍后重试" |
| `404` | 提示用户:"未找到指定记录,请确认 ID 是否正确" |
| `400` | 将响应体中的 `detail` 字段内容告知用户 |

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
| curl 错误 / HTTP 状态码 | AI 应对策略 |
|------------------------|------------|
| `curl: (7) Connection refused` | 提示用户:"本地服务未启动,请在 backend 目录运行 `uvicorn main:app --reload --port 8000`" |
| `503` | 提示用户:"DASHSCOPE_API_KEY 未配置或无效,请检查 backend/.env 文件" |
| `502` | 提示用户:"AI 接口调用失败,请稍后重试" |
| `404` | 提示用户:"未找到指定记录,请确认 ID 是否正确" |
| `400` | 将响应体中的 `detail` 字段内容告知用户 |

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

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

-H "Content-Type: application/json"
-d "{"holdings": $(cat /tmp/holdings_update.json), "label": " 截图导入"}"

rm /tmp/holdings_update.json

text

成功后告知用户持仓已更新。

Vague Triggers

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The rollback triggers include very broad phrases such as '撤销' and '恢复到上次', which can easily appear in ordinary conversation unrelated to portfolio rollback. Because rollback is a high-impact state-changing action, overly broad activation increases the chance that an agent misroutes benign user input into a destructive workflow and presents a dangerous confirmation preview.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/api-docs.md (reported line 68)May include surrounding context.

md
|--------|--------|
| `400` | "未检测到上传的图片,请确认文件路径是否正确" |
| `502` | "AI 接口调用失败,请稍后重试" |
| `503` | "DASHSCOPE_API_KEY 未配置,请检查 backend/.env" |

---

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/api-docs.md (reported line 109)May include surrounding context.

md
|--------|--------|
| `400` | "未检测到上传的图片,请确认文件路径是否正确" |
| `502` | "AI 接口调用失败,请稍后重试" |
| `503` | "DASHSCOPE_API_KEY 未配置,请检查 backend/.env" |

---

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description and usage instructions are presented entirely in Chinese, with no indication that other languages are supported or that the language choice is optional. Under the policy, forcing a specific language without user opt-in is a natural-language locale violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README encourages users to upload brokerage screenshots to an AI vision service but does not prominently warn that these images may contain highly sensitive financial and personal data. In this skill context, that omission is more dangerous because portfolio screenshots can expose holdings, account values, names, and broker details to third-party model providers or logs.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

SQP-3 适用于所有文件类型。描述文本完全以中文规定技能用途,且整份说明均默认代理以中文与用户交互,没有说明可根据用户语言偏好切换或先征求用户语言选择。依据规则,强制单一语言且无用户 opt-in 可能构成语言/locale policy 违反。

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

This workflow uploads user-provided screenshots and notes to an 'external/upload' endpoint for AI analysis, which can expose sensitive financial data such as holdings, asset values, and account information. Even though the base URL is localhost, the endpoint is explicitly tied to an external AI dependency via DASHSCOPE, so the skill facilitates transmission of sensitive content beyond the immediate agent context.

Content

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

Step 1:上传截图,获取分析结果

bash
curl -sS -X POST http://localhost:8000/api/external/upload \
  -F "images=@<图片绝对路径>" \
  -F "notes=<用户补充说明,无则省略>" \
  -F "portfolio_date=<YYYY-MM-DD,无则省略>"

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 124)May include surrounding context.

查询现金(只读,直接执行)

bash
curl -sS http://localhost:8000/api/cash

取响应中的 amount 字段,告知用户当前现金余额。

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

该 markdown 文件适用 SQP-1。工作流 D 的触发词如“操作记录”“写日记”以及模式“今天买了/卖了”语义较宽,可能在用户仅讨论投资行为或回顾当天操作时被误判为要调用该技能执行日记写入。文档也未提供排除条件或负例来限定何时只查询/讨论、何时真正触发记录。

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 175)May include surrounding context.

用户确认后执行:

bash
curl -sS -X POST http://localhost:8000/api/diary \
  -H "Content-Type: application/json" \
  -d "{\"date\": \"<YYYY-MM-DD>\", \"type\": \"<type>\", \"code\": \"<code>\", \"remark\": \"<remark>\", \"mood\": \"<mood>\"}"

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The API guide instructs the AI to respond with fixed Chinese phrases in the error-handling table, and similar Chinese-only user-facing response instructions appear throughout the document. Because the file does not offer user opt-in or explain that the skill is intentionally limited to a Chinese-speaking context, this is a natural-language locale policy issue.

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

md
# 先将图片转为 Base64
B64=$(base64 -i <图片路径>)

curl -sS -X POST http://localhost:8000/api/analyze \
  -H "Content-Type: application/json" \
  -d "{
    \"base64_images\": [\"${B64}\"],

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

即用命令

bash
curl -sS -X POST http://localhost:8000/api/holdings/bulk \
  -H "Content-Type: application/json" \
  -d "{
    \"label\": \"<YYYY-MM-DD> 截图导入\",

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

即用命令

bash
curl -sS http://localhost:8000/api/cash

AI 需要提取的关键响应字段

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

即用命令

bash
curl -sS -X POST http://localhost:8000/api/diary \
  -H "Content-Type: application/json" \
  -d "{
    \"date\": \"<YYYY-MM-DD>\",

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

即用命令

bash
curl -sS http://localhost:8000/api/curve

AI 需要提取的关键响应字段

Static analysis

No suspicious patterns detected.