Back to skill

Security audit

报价单生成

Security checks for vulnerabilities and agentic risk

Overview

The skill coherently generates quotation spreadsheets, but it does not specify safeguards against spreadsheet formula injection when copying user-controlled text into Excel cells.

Review this skill before installing if generated quotation files may be sent to customers or opened by others. It should treat all user and price-list text as untrusted, write text fields as literal strings, and allow formulas only in trusted template-controlled cells.

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

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:94
Finding

Spreadsheet Formula Injection Through Untrusted Cell Values

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 94–130
Vulnerability Type: Spreadsheet formula injection
Risk Level: Medium

Vulnerable Code Segments

Product data derived from user input, lines 94–102:

markdown
1. 从用户输入中提取需要报价的产品名称列表。
2. 在已解析的物料价格表中查找每个产品:
   - 若一个 `materialName` 只对应一个 `specModel` → 直接确定
   - 若一个 `materialName` 对应多个 `specModel` → **必须向用户发起澄清**,列出所有可选型号及对应价格,请用户确认
3. **澄清规则**:
   - 若用户已在消息中明确指定了型号 → 视为已澄清,直接继续
   - 若当前消息是对上一轮澄清的补充(提供了缺失的型号/品牌/规格)→ 视为澄清完成,**禁止再次发起澄清**,继续执行后续流程
   - 需要澄清的产品必须是物料价格表中真实存在的,禁止自行创造
   - 如果用户输入的产品在物料表中**找不到**,也要告知用户"未找到该产品,请检查名称或补充到物料表中"

Untrusted values placed into fill operations, lines 107–117:

markdown
1. 根据确认后的产品-型号-单价映射,结合模板列映射,生成填充数据:
   - 行号规则:第 N 条产品行 = `start_row + N`
   - **严禁** 把产品写在 `start_row`(表头行),必须从 `start_row + 1` 开始
   - 数量默认填 `1`,若用户在输入中明确指定了数量则使用指定值
2. 计算总价:
   - 若模板金额列已有公式 → 只填数量和单价,让公式自动计算
   - 若模板金额列无公式 → 计算 `数量 × 单价` 填入金额列
3. 填充单值区域:
   - 客户名称、日期、报价单号等,若用户提供则填入对应位置
   - 日期默认为当天,格式与模板中原有日期格式保持一致
4. 输出 `fill_operations` 结构,参见 [references/data-schema.md](references/data-schema.md)。

Direct workbook writes without sanitization, lines 124–130:

markdown
1. 复制用户上传的模板到临时目录,生成唯一文件名(UUID 后缀)。
2. 使用 `openpyxl` 遍历 `fill_operations`,写入对应单元格:
   - `col` 用 `column_index_from_string()` 转为列索引
   - `row` 必须 > 0,`col` 不能为空
   - 对于已有公式的单元格,若需要覆盖,先清除原有公式再写入值
3. 保存工作簿,返回生成文件的路径和名称。

Technical Analysis

The workflow accepts text from user messages and uploaded Excel or CSV price lists, places that text into fill_operations, and then writes each value directly to an Excel workbook through openpyxl. No validation or output encoding is specified for text beginning with spreadsheet formula markers.

In particular, a string beginning with = can be stored by openpyxl as a formula rather than as literal text. Other leading characters commonly associated with spreadshe ...[truncated 2447 chars]

Remediation
View remediation

Remediation Suggestions

  1. Separate trusted formulas from untrusted text. Permit formulas only in explicitly identified template formula cells. Values originating from users, CSV files, or uploaded workbooks must be written as literal text.
  2. Sanitize dangerous prefixes. Before writing an untrusted string, normalize and inspect its first meaningful character. Treat =, +, -, and @ as dangerous, including when preceded by spaces, tabs, carriage returns, line feeds, or other control characters.
  3. Force literal cell values. Prefix dangerous values with a single quote or explicitly set the cell to a string type using a safe helper designed for the selected Excel library. Verify that the chosen method remains literal after saving and reopening the workbook.
  4. Validate formula cells with an allowlist. Preserve or generate formulas only for expected fields such as the total-price column. Validate generated formulas against a strict pattern, such as multiplication of the quantity and unit-price cells on the same row.
  5. Do not copy formulas from untrusted source data. When parsing uploaded workbooks, distinguish formulas from displayed values and reject formulas in fields expected to contain names, models, units, remarks, or identifiers.
  6. Apply field-specific validation. Require numeric fields to parse as bounded numeric values and restrict identifier fields such as quotation numbers to an appropriate character allowlist.
  7. Add regression tests. Test direct and whitespace-prefixed payloads beginning with =, +, -, and @. Save and reopen each generated workbook to confirm that untrusted values remain literal strings while approved template formulas continue to work.
  8. Document the trust boundary. State explicitly that uploaded price lists, quotation templates, and user-provided metadata are untrusted and must not introduce new executable spreadsheet expressions.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest description lists activation scenarios such as '用户需要生成报价单' and keywords like '生成报价' and '填写报价', which are broad natural-language phrases without clear invocation boundaries or exclusion conditions. Because this is a markdown/manifest-style section, the lack of specific trigger constraints could cause unintended matching on ordinary business requests.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This markdown file is written entirely in Chinese and presents the schema, examples, and operational rules only in that language, with no indication that users may choose another language or locale. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The name and description are presented in Chinese, and the file does not indicate that users may interact in another language or choose their preferred locale. Under the stated policy, a skill should not impose a language or locale without opt-in unless the restriction is documented and justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The markdown explains that the skill will copy the uploaded template, write values into cells, and save a workbook to produce a new file path, which affects user files and document contents. However, the description does not explicitly warn the user that the uploaded template will be processed and a modified derivative file will be generated and stored.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.