Back to skill

Security audit

合同卫士 / Contract Guardian

Security checks for vulnerabilities and agentic risk

Overview

This contract-review skill is coherent and local-only, but needs Review because it can expose and persist sensitive contract details more broadly than its privacy language suggests.

Install only if you are comfortable with local scripts reading contract files and storing contract metadata on disk. Use a private CG_DATA_DIR with restrictive permissions, avoid untrusted filenames or JSON values, and treat generated reports/diffs as sensitive because they may include names, contact details, contract terms, excerpts, and local file paths. Important contracts should still be reviewed by qualified legal counsel.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:34
Finding

Unquoted User-Controlled File Paths in Documented Shell Workflows

Content
View full analysis
``` ```bash python3 scripts/key_info_extractor.py --action summary --text-file ``` ```bash python3 scripts/risk_analyzer.py --action full-report --text-file ``` ```bash python3 scripts/contract_parser.py --action extract-text --file ``` ```bash python3 scripts/key_info_extractor.py --action extract --text-file ``` ```bash python3 scripts/contract_store.py --action archive --data '' ``` ```bash python3 scripts/contract_comparator.py --action diff-report --file1 --file2 ``` ### Technical Analysis The Skill instructs an agent to interpolate user-supplied file paths and JSON data directly into shell command strings. The placeholders are not quoted, and the instructions do not require an argument-array process API or prohibit shell interpretation. If an agent implements these workflows by constructing a command string and passing it to a shell, shell metacharacters in a supplied path can terminate the intended argument and introduce an additional command. Quoting the JSON argument with single quotes is also insufficient when attacker-controlled JSON can itself contain a single quote. The Python scripts use `argparse` and do not independently invoke a shell. The vulnerability arises at the Skill orchestration layer when the documented commands are assembled and executed through a shell. ### Attack Path 1. An attacker provides or references a contract whose filename contains shell metacharacters, such as: ```text contract.txt; attacker-command ``` 2. The user asks the agent to parse, analyze, or compare that contr ...[truncated 1190 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/key_info_extractor.py:176
Finding

Sensitive Contract and Contact Data Is Returned Without Centralized Redaction

Content
View full analysis
Dict[str, Optional[str]]: """Extract contact information.""" result = { "phone": None, "email": None, "address": None, } phone_match = re.search( r"(?:电话|联系电话|手机|Tel)[::]\s*([\d\-+() ]{7,20})", text, ) if phone_match: result["phone"] = phone_match.group(1).strip() email_match = re.search( r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}", text, ) if email_match: result["email"] = email_match.group(0) addr_patterns = [ r"(?:地址|住所|注册地址)[::]\s*(.{5,100}?)(?:\n|$|电话|邮编|联系)", ] for pattern in addr_patterns: match = re.search(pattern, text) if match: result["address"] = match.group(1).strip() break return result ``` The extracted object and generated summary are then emitted directly: ```python if args.action == "extract": output_success(info) elif args.action == "summary": summary = generate_summary(info) output_success({ "info": info, "summary": summary, }) ``` In `scripts/risk_analyzer.py`, excerpts from the original contract are returned without redaction: ```python if matches: unique_matches = list(dict.fromkeys(matches)) risks.append({ "category_id": category["id"], "category_name": category["name"], "severity": category["severity"], "matched_text": unique_matches[:3], "description": category["descrip ...[truncated 3089 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/contract_store.py:27
Finding

Plaintext Contract Metadata Storage Uses Ambient Filesystem Permissions and Non-Atomic Writes

Content
View full analysis
str: """Ensure the data directory exists and return its path.""" os.makedirs(DATA_DIR, exist_ok=True) return DATA_DIR def get_data_file(filename: str) -> str: """Return the complete path for a data file.""" ensure_data_dir() return os.path.join(DATA_DIR, filename) ``` The contract store is written as plaintext using the process's ambient umask, and the target file is overwritten directly: ```python def _save_store(contracts: List[Dict[str, Any]]) -> None: """Save archived contract data.""" store_path = get_data_file(STORE_FILE) ensure_data_dir() with open(store_path, "w", encoding="utf-8") as f: json.dump( contracts, f, ensure_ascii=False, indent=2, default=str, ) ``` The stored record contains confidential metadata and an optional source path: ```python record = { "id": contract_id, "title": data.get("title", "未命名合同"), "party_a": data.get("party_a"), "party_b": data.get("party_b"), "start_date": data.get("start_date"), "end_date": data.get("end_date"), "amount": data.get("amount"), "file_path": data.get("file_path"), "notes": data.get("notes"), "archived_at": now, "status": "active", } contracts.append(record) _save_store(contracts) ``` ### Technical Analysis `os.makedirs(DATA_DIR, exist_ok=True)` and `open(..., "w")` do not enforce owner-only access. Effective permissions depend on the runtime's umask and on any pre-existing directory or file. On a permissively configured multi-user system, another local account may be able to traverse t ...[truncated 1795 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (23)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

声明描述的是一个合同审查助手,核心能力应包括风险条款识别、关键信息抽取和到期日追踪。但提供的代码并未执行这些审查型任务,而是专注于比较两份合同之间的文本与条款差异,输出相似度、增删统计和差异报告。这属于不同的主要功能方向。虽然合同对比与合同审查相关,但它不能合理等同于声明中的三项核心能力,因此构成明显的描述-行为不一致。付费校验属于附加行为,不是主要安全问题,但也未在声明中体现。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

声明描述的是一个面向合同审查分析的 AI 助手,核心能力应包括语义分析、条款风险识别、结构化要点抽取和期限管理。但提供的代码仅负责文件格式检测、读取 TXT/MD/PDF/DOCX 文档、提取纯文本、统计字符/行数,并在 CLI 输出前进行脱敏。代码中没有任何针对合同内容的审查、分类、风险评分、实体抽取、日期识别、提醒或追踪机制。因此其实际主功能与声明的主功能存在明显偏差。另有订阅校验与付费版格式支持限制,这属于额外业务逻辑,虽不一定恶意,但也未在声明中体现。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

声明的核心定位是“AI合同审查助手”,其中最关键的能力应是对合同文本进行分析,如识别风险条款和提取关键信息。但该代码块只处理合同元数据的持久化存储、状态更新、搜索以及到期合同统计提醒。虽然“追踪到期日”这一点与声明部分一致,但整体主功能与“合同审查”明显不符,且没有任何文本解析、NLP、条款分析或风险识别逻辑。代码还加入了免费版/付费版的数量限制和搜索权限控制,这些也未在声明中体现。因此该描述与实际行为存在实质性不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

声明描述的是较完整的合同审查助手,重点在风险识别、关键信息提取和到期日追踪。该代码块只覆盖了其中一部分:关键信息提取,并且通过正则提取若干固定字段后输出摘要。虽然包含违约条款和日期提取,但并没有进行风险评估、风险分类、提醒/追踪机制或任何持续性到期管理功能。因此,代码与声明存在部分重合,但整体能力范围明显低于且不同于声明的核心用途,应判定为描述与实际行为不完全匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

代码与声明中的“识别风险条款”部分基本一致:它会对合同文本进行规则匹配,识别12类风险条款并生成报告。但声明还包括“提取关键信息、追踪到期日”,而提供的代码中没有看到任何关键信息抽取逻辑,也没有任何到期日识别、日期计算、提醒或跟踪功能。代码的主要目的更窄,集中在风险条款检测,而非完整的合同审查助手。因此存在描述与实际行为不完全一致的能力夸大,属于实质性不匹配。

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill invokes local scripts, reads environment variables, and archives contract data, but does not declare any explicit tool scope such as allowed-tools or permissions. This creates an authorization ambiguity where a host agent may grant broader file/env access than users expect, which is risky given the sensitivity of contract contents and local storage behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

L014 明确规定“你始终使用中文与用户沟通”,这是对语言/locale 的硬性限制,但文档中没有提供用户选择语言的机制,也没有说明该技能仅面向特定中文场景或地区。根据语言/locale 政策,这类无用户选择的强制语言要求属于自然语言策略违规。

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Broad trigger phrases like '合同模板' combined with 'or similar intent' can cause accidental activation in unrelated conversations. In a skill that reads files, analyzes contracts, and archives data, overbroad invocation increases the chance of unintended processing of sensitive documents or launching local scripts without sufficiently explicit user intent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

L299 再次规定“始终使用中文与用户沟通”,延续了前文的硬性语言约束,且同样没有提供用户 opt-in 或替代语言选项。该表述会使技能在非中文用户场景下无法遵循用户语言偏好。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file is natural-language content, so locale policy applies. The README consistently forces a single language for installation, usage, warnings, and support information, with no user opt-in, alternate language option, or statement that the skill is intended only for a Chinese-speaking or region-specific audience.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document presents ready-to-use contract templates without a clear warning that they are only reference materials and may not be legally sufficient for a user's jurisdiction, transaction type, or risk profile. In a contract-review skill, users are especially likely to rely on the templates directly, which can lead to unenforceable terms, missing protections, or regulatory noncompliance.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The file is entirely written in Chinese and presents itself as a reference for an AI review assistant, but it does not state that the skill is China-specific or otherwise justify a Chinese-only locale requirement. Under the language/locale policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module description and all user-facing strings are in Chinese, indicating the skill operates in a fixed language/locale. There is no opt-in, language selection, or documented justification that this is a region-specific tool, which creates a natural-language policy concern under the locale-choice requirement.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The tool reads user-supplied contract files and returns raw excerpts, diffs, filenames, and a full markdown report without any warning, masking, or output minimization. Because contracts routinely contain sensitive commercial and personal data, this creates a real risk of unintended disclosure through console output, logs, downstream consumers, or copied reports.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module docstring presents the skill entirely in Chinese, and the rest of the user-facing strings in the file are also Chinese-only. This imposes a specific language on users without offering a language choice or documenting a justified region-specific requirement, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The command-line description, argument help text, and runtime error/success messaging are written only in Chinese. Because the skill does not provide a language selection mechanism or clearly justify a Chinese-only locale scope, this is a natural-language policy issue under the stated rules.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The module description is entirely in Chinese and presents the skill as operating in that language by default, with no indication that users can choose another language or locale. Under the policy, forcing a specific language without opt-in is a natural-language policy violation unless the locale constraint is clearly documented and justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This code explicitly extracts phone numbers, email addresses, and addresses from contract text, and later returns them in command output. Although the module has docstrings describing extraction behavior, there is no user-facing warning in the CLI help or runtime output that sensitive personal or business contact data may be parsed and emitted, which is relevant for a contract-processing tool.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code's natural-language interface and user-facing descriptions are entirely in Chinese, including the module description and later CLI help/output strings, with no indication that the user can choose another language. The policy requires flagging language or locale constraints when they are imposed without user opt-in or clear justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code file contains natural-language documentation entirely in Chinese, and later user-facing error/help messages are also emitted only in Chinese. Under the policy, forcing a specific language without user opt-in or a clearly documented regional constraint is a language/locale policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The raised ValueError messages and other user-visible text in this file are written only in Chinese, which imposes a fixed locale on users. Because no opt-in, fallback language, or explicit region-specific justification is present in the file, this conflicts with the language/locale policy.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The documentation at L014 makes an absolute claim that contract content will not be uploaded to any external service. Later support instructions at L173-L175 describe external issue submission and email contact, which does not by itself prove contract upload, but creates tension with the absolute local-only statement in the same document.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

Natural-language strings throughout the file, including the module description, CLI description, argument help, and error messages, are only in Chinese. This can constitute a language/locale policy issue because the skill forces a specific language without any user opt-in or documented justification for being Chinese-only.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.