Back to skill

Security audit

Invoice From Email

Security checks for vulnerabilities and agentic risk

Overview

This skill matches an invoice-from-email workflow, but it handles mailbox secrets and untrusted email attachments in ways that users should review carefully before installing.

Install only if you are comfortable granting mailbox access for invoice processing. Do not let the agent print or paste mailbox passwords or app tokens; use a revocable app password or OAuth-style credential where possible. Run it in a contained workspace, process only trusted invoice emails, avoid opening generated spreadsheets with external links/macros enabled, and prefer a version that uses a private temp directory and safe ZIP extraction.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (5)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:86
Finding

Mailbox Credentials Are Printed into Agent and Terminal Context

Content
View full analysis
/dev/null ``` The accompanying instructions require checking whether `IMAP_PASS` is populated and later direct the Skill to read the email address and password from the same `.env` file. ### Technical Analysis The preflight check only needs to determine whether the email integration is configured. Printing the entire `.env` file is unnecessary for that purpose and violates least privilege. Because the command uses `cat`, every variable in the file—including an IMAP password, application password, or authorization token—is written to standard output. In an agent-driven environment, that output can enter the conversation context, execution logs, retained transcripts, screenshots, or telemetry. The embedded Python scripts do not access the credentials directly, and no credential-exfiltration endpoint was identified. Nevertheless, exposing the secret to the agent and its output channels materially expands the credential's exposure surface. ### Attack Path 1. A user invokes the invoice-processing Skill. 2. The mandatory preflight instructions cause the agent to execute the `cat` command. 3. The complete email configuration file is printed. 4. The mailbox password or application token becomes part of terminal output or agent context. 5. Any party or component with access to retained logs, transcripts, or output can recover and reuse the credential. ### Impact Assessment Successful exposure grants whatever access the configured email credential permits. Depending on the provider and token scope, this can include reading private messages and attachments, searching historical email, downloading sensitive documents, and possibly sending mail. ...[truncated 139 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:232
Finding

Untrusted ZIP Entries Can Escape the Working Directory and Overwrite Files

Content
View full analysis
unzip -o *.zip 2>/dev/null ``` ```python import zipfile, os for zf_name in [f for f in os.listdir('.') if f.endswith('.zip')]: z = zipfile.ZipFile(zf_name) for info in z.infolist(): name = info.filename.encode('cp437').decode('gbk', errors='replace') if name.lower().endswith('.pdf'): with z.open(info) as src, open(name, 'wb') as dst: dst.write(src.read()) print(f'Extract: {name}') ``` ### Technical Analysis ZIP files are downloaded from email and must be treated as attacker-controlled. The fallback extraction logic decodes each archive entry name and passes it directly to `open(name, 'wb')`. There is no rejection of: - Absolute paths - Parent-directory components such as `..` - Drive-qualified paths on Windows - Symbolic-link entries - Paths resolving through pre-existing symlinks - Duplicate entries - Oversized or highly compressed entries The `.pdf` suffix check does not prevent traversal. A path such as `../../target.pdf` still passes the check. Opening the destination in `wb` mode also truncates an existing file without confirmation. The preceding `unzip -o` command additionally enables unconditional overwrite behavior. Its traversal protections may vary by implementation and should not be relied upon as the security boundary. ### Attack Path 1. An attacker sends an invoice-themed email containing a crafted ZIP attachment. 2. The Skill downloads the attachment into its working directory. 3. The archive contains an entry such as `../../configuration/target.pdf`. 4. The entry passes the case-insensitive `.pdf` suffix check. 5. The extraction code opens the decoded path relative to the working directory. 6. Path resolution escapes the extraction directory. 7. An existing fil ...[truncated 648 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:260
Finding

Shared Predictable Temporary Files Permit Cross-Run Data Injection and Deletion

Content
View full analysis
/*.pdf; do python3 "$EXTRACT" "$pdf" "/tmp/invoice_${TS}_${i}.md" python3 "$PARSE" "/tmp/invoice_${TS}_${i}.md" -o "/tmp/invoice_${TS}_${i}.json" i=$((i+1)) done ``` ```bash /usr/bin/python3 /Users/lulingyan/.workbuddy/skills/invoice-from-email/scripts/generate_excel.py /tmp/ /expense-list.xlsx ``` ```bash rm -f /tmp/invoice_*.md /tmp/invoice_*.json ``` ```python def load_json_files(json_dir: str) -> dict: """Load all JSON files in a directory, grouped by type.""" result = {"invoice": [], "itinerary": [], "train": [], "unknown": []} for fname in sorted(os.listdir(json_dir)): if not fname.endswith(".json"): continue with open(os.path.join(json_dir, fname), "r", encoding="utf-8") as f: data = json.load(f) t = data.get("type", "unknown") if t in result: result[t].append(data) else: result["unknown"].append(data) return result ``` ### Technical Analysis Temporary filenames are generated from a timestamp with one-second resolution and a sequential counter. They are therefore predictable and are placed in the globally shared `/tmp` directory. The Excel command passes the entire `/tmp` directory to `generate_excel.py`. The loader then imports every lowercase `.json` file in that directory rather than only files created by the current run. It performs no provenance check and no strict schema validation before using the data. Cleanup uses broad wildcards and can delete matching files created by concurrent Skill runs or unrelated processes. Depending on platform configuration and filesystem pro ...[truncated 1329 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_excel.py:126
Finding

Untrusted Invoice Metadata Can Be Written as Executable Spreadsheet Formulas

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:26
Finding

Unpinned Package Installation Creates a Mutable Supply-Chain Boundary

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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (23)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个端到端票据处理流程:从邮箱抓取附件、解析PDF/图片内容、使用PyMuPDF/Tesseract/PaddleOCR等多级提取,并将票据排版合并,同时输出双Sheet Excel。实际代码块仅是后处理环节中的 Excel 生成脚本。它读取 parse_invoice.py 产出的 JSON 文件,做分组、配对、金额校验并生成双Sheet工作簿。虽然“双Sheet费用清单Excel”这一点与声明部分一致,但声明中的核心能力——邮箱访问、附件下载、OCR/文本提取、A4合并排版——在此代码中完全不存在。因此该代码块与整体声明存在明显的描述-行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a broader end-to-end workflow: email retrieval, attachment download, intelligent multi-engine OCR/text extraction, invoice/itinerary merging, and Excel expense-sheet creation. This code chunk implements only the PDF merge/layout portion. It operates on a local input directory, uses PyMuPDF for rendering/composition, and includes heuristics for grouping files and trimming trivial pages. While the A4 merge behavior does align with part of the description, several major claimed capabilities are absent: no mailbox interaction, no OCR engines or fallback logic, and no Excel output. Therefore the description materially overstates what this code actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

声明描述的是一个端到端票据处理工作流,包含邮箱访问、附件获取、OCR/文本提取、文档合并排版和 Excel 清单生成等多个环节。实际代码块只覆盖其中的“智能三级文字提取”子功能,而且目标输出是 Markdown 文本供上游解析。虽然三级提取与‘零 OCR 依赖即可处理 90%+ 电子发票’这一部分基本一致,但整体声明把该技能描述为完整自动化系统,而当前代码并未实现其余关键能力。因此属于描述与代码行为的实质性不匹配;不是因为代码有额外未声明的危险能力,而是因为声明显著高于实际实现范围。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

代码功能集中在“解析已提取好的 Markdown 文本并输出结构化 JSON”。它读取单个 .md 文件,基于正则和启发式规则检测文档类型,并提取发票号码、金额、日期、行程起终点、火车票车次等字段。这与声明的端到端自动化流程存在明显差异:声明强调邮件获取附件、OCR提取、版面合并和Excel汇总,而这些核心能力在该代码片段中均不存在。相反,代码体现的是其中某个中间环节——文本结构化解析。另外,代码还支持火车票解析,这属于声明未覆盖的能力。基于主功能和能力范围的明显不一致,应判定为描述与行为不匹配。

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill directs the agent to read mailbox credentials from a local .env and process mailbox contents containing sensitive financial data. This combines secret access with broad data collection, raising the risk of account compromise and privacy breach if the agent, logs, or workspace are exposed.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

The explicit instruction to cat another skill's .env is direct credential access behavior. Reading plaintext mailbox secrets from disk is dangerous because it exposes them to the agent context, logs, shell history, and any downstream components that can inspect command output.

Content

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

1. 检查邮箱配置

bash
cat /Users/lulingyan/.workbuddy/skills/imap-smtp-email/.env 2>/dev/null

.env 存在且 IMAP_PASS= 非空 → 通过。否则暂停,执行下方「首次使用:邮箱授权引导」。

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Collecting an email authorization code from the user and writing it into a local .env stores a highly sensitive secret in plaintext. If the workstation, repo, backups, or other tools can read that file, an attacker could gain persistent access to the user's mailbox.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

Writing mailbox credentials into a local .env creates a persistent plaintext secret on disk and broadens access to anyone or anything with filesystem visibility. In this context, the skill is processing financial email, so mailbox compromise would expose sensitive documents and account data.

Content

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

收集到邮箱地址和授权码后,用 Write 工具写入:

text
路径:/Users/lulingyan/.workbuddy/skills/imap-smtp-email/.env

(参考 imap-smtp-email SKILL.md 中 Configuration 章节的模板)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
88% confidence
Finding

The cleanup command uses a broad wildcard deletion pattern in /tmp, which can remove files outside the current run if naming collides with other sessions or users. In agentic contexts, parameterized or overly broad destructive commands are risky because they may delete unintended data without confirmation.

Content

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

bash
# 清理临时提取和解析文件
rm -f /tmp/invoice_*.md /tmp/invoice_*.json

# 清理非 PDF/Excel 中间文件
cd <工作目录>

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill requests file read/write-like behavior in its instructions but declares no explicit tool scope or permissions boundary. That makes sensitive operations such as reading credentials and writing config files less transparent and easier to over-grant in deployment.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

2. pip install pytesseract

Linux

sudo apt install tesseract-ocr tesseract-ocr-chi-sim pip install pytesseract

text

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation advertises mostly local processing but introduces optional MinerU cloud extraction, which can send sensitive invoice contents to a third party. That broadens data exposure in a way users may not expect from the stated local-first design.

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 and writing mailbox credentials in another skill's .env, expanding its authority beyond invoice processing into credential handling. Cross-skill secret access increases the chance of credential exposure, accidental overwrite, or unauthorized reuse of email account access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill handles email credentials but does not present a clear warning about secrets handling, storage risk, or least-privilege practices. Users may reveal authorization codes or permit local storage without understanding the security implications.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Bulk email search and attachment download can expose large volumes of private financial documents, yet the workflow lacks an explicit privacy notice or consent checkpoint. In context, invoices and itineraries are highly sensitive personal and business records.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

工作目录:<当前 workspace>/invoices_YYYYMMDD/(按当天日期命名,例如 /Users/lulingyan/WorkBuddy/2026-07-14-16-38-40/invoices_20260714/)

bash
mkdir -p <工作目录>

# 逐封邮件下载全部附件
node scripts/imap.js download <UID> --dir <工作目录>

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

工作目录:<当前 workspace>/invoices_YYYYMMDD/(按当天日期命名,例如 /Users/lulingyan/WorkBuddy/2026-07-14-16-38-40/invoices_20260714/)

bash
mkdir -p <工作目录>

# 逐封邮件下载全部附件
node scripts/imap.js download <UID> --dir <工作目录>

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code file contains natural-language instructions and runtime output entirely in Chinese, including the usage text shown to users. Under the policy, forcing a specific language without user opt-in is a locale-policy violation unless the constraint is explicitly 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
94% confidence
Finding

This code hard-codes Chinese language settings in both OCR engines: Tesseract uses "chi_sim+eng" and PaddleOCR is initialized with lang="ch". The file’s natural-language descriptions also position the tool around Chinese invoices, but the script itself does not provide any user-selectable locale option, which is a language-policy constraint present in a code file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The skill name, description, instructions, and installation guidance are all Chinese-specific, including mandatory setup for chi_sim Tesseract data. This effectively forces a specific language/locale without documenting opt-in or offering an alternative language path.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The workflow states the search should avoid using --limit to prevent truncation, yet the sample commands immediately use --limit 500. This is an intent/behavior mismatch in the documented operation of the skill and can affect completeness expectations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code file contains natural-language instructions and usage text entirely in Chinese, including the module docstring shown to users. Under the policy, forcing a specific language without user choice is a natural-language policy violation unless the locale restriction is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The auto_merge_folder docstring says files are paired by '共同前缀' (common prefix), but the actual implementation derives a grouping key via _extract_group_key using bracket contents or suffix removal, not prefix matching. This is an intent/documentation mismatch that could mislead users about how files are associated.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.