Back to skill

Security audit

客户脉搏 / Customer Pulse

Security checks for vulnerabilities and agentic risk

Overview

This CRM skill is coherent and local-only, but it needs review because it stores and can export customer personal data with under-described protections.

Install only if you are comfortable with a local CRM that stores customer names, phone numbers, budgets, and follow-up notes in plaintext files. Protect the data directory and any CSV exports, avoid exporting raw data into chat output, and confirm deletion intent before asking the agent to remove records.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/utils.py:88
Finding

CRM Data Is Stored Without Restrictive Filesystem Permissions

Content
View full analysis
None: """将数据写入 JSON 文件。 Args: filepath: 目标文件路径。 data: 待写入的数据。 """ os.makedirs(os.path.dirname(filepath), exist_ok=True) with open(filepath, "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=2, default=str) ``` ### Technical Analysis The application stores customer records and follow-up data as unencrypted JSON. These records can contain names, full phone numbers, companies, budgets, product interests, and commercially sensitive follow-up notes. The function creates the parent directory and output file without explicitly applying restrictive permissions. Their effective permissions therefore depend on the process umask and the permissions of an existing directory. In an environment with a permissive umask or pre-created shared data directory, other local users or processes may be able to read CRM data. The issue also affects custom storage locations supplied through `CP_DATA_DIR`. The code does not verify whether that directory is private, owned by the current user, a symbolic link, or accessible by other users. ### Attack Path 1. The Skill runs with a permissive umask or with `CP_DATA_DIR` pointing to a shared or insufficiently protected directory. 2. A user adds customer records or follow-up notes. 3. `write_json_file` creates or updates `customers.json` and `followups.json` without enforcing private permissions. 4. Another local account or process with filesystem access to that directory opens the files. 5. The attacker obtains the stored customer identities, phone numbers, budgets, sales status, and follow-up content. This path requires local filesystem access and an environment in which the ...[truncated 692 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/customer_store.py:343
Finding

Phone-Number Masking Can Be Bypassed and CSV Export Returns Raw PII

Content
View full analysis
str: """对手机号进行脱敏处理。 将手机号中间 4 位替换为 ****。 Args: phone: 原始手机号。 Returns: 脱敏后的手机号,如 138****8000。 若格式不符合,返回原始值。 """ if not phone: return phone phone = phone.strip() if re.match(r"^1[3-9]\d{9}$", phone): return phone[:3] + "****" + phone[7:] return phone ``` CSV export writes raw customer records without invoking `mask_phone`: ```python def export_customers(data: Optional[Dict[str, Any]] = None) -> None: """导出客户数据到 CSV 格式。 可选字段: file_path(若不指定则输出到 stdout) Args: data: 可选的配置字典。 """ customers = _get_customers() if not customers: output_error("暂无客户数据可导出", code="NO_DATA") return file_path = data.get("file_path") if data else None fieldnames = ["id", "name", "phone", "company", "product_interest", "budget", "stage", "source", "created_at", "updated_at"] try: if file_path: with open(file_path, "w", encoding="utf-8", newline="") as f: writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() for c in customers: row = {k: c.get(k, "") for k in fieldnames} writer.writerow(row) output_success({"message": f"已导出 {len(customers)} 条客户数据到 {file_path}", "count": len(customers)}) else: output_buf = io.StringIO() writer = csv.DictWriter(output_buf, fieldnames=fieldnames) writer.writeheader() for c in customers: row = {k: c.get(k, "") for k in fieldnames} writer.writerow(row) output_success( ...[truncated 2598 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description presents a lightweight follow-up CRM assistant, but the skill also performs churn prediction, risk scoring, budget-risk aggregation, and paid-feature gating that are not reflected in the top-level description. This mismatch can mislead users and reviewers about the sensitivity and breadth of processing, especially because predictive analysis on customer data may influence sales decisions and process more business-sensitive information than simple tracking. The context makes this more dangerous because the skill handles customer identities, phone numbers, budgets, and follow-up history.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill invokes local scripts, reads environment variables, and stores data on disk, but it does not declare an explicit tool/permission scope. That creates a transparency and containment gap: a host may grant broader capabilities than reviewers or users expect, and file/env access can expose CRM data or write to unintended locations if downstream scripts are unsafe. In a CRM context handling customer PII, undeclared file and env capabilities are more sensitive than in a trivial note-taking skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The instruction says the agent 'always uses Chinese' when communicating with the user. This is a language-policy constraint expressed as a universal rule, and the file does not offer an alternative language choice or require user opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README encourages storing, importing, and exporting customer records containing phone numbers, company names, budgets, and follow-up notes, but provides no meaningful warning about the sensitivity of this personal and business data or safe handling expectations. In a CRM context, this omission can lead users to place regulated or confidential data into local files and CSV backups without considering access controls, retention, redaction, or secure storage, increasing the risk of privacy and confidentiality exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The guide explicitly instructs users to collect customer personal data such as names, companies, and contact details, and later describes CSV export of that data, but it provides no privacy, retention, access-control, consent, or secure-handling guidance. In a CRM context this omission can lead to improper processing, insecure storage, and regulatory noncompliance involving personally identifiable information.

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 file contains user-facing natural-language descriptions entirely in Chinese, including the module name and behavior description, with no indication that the user can choose another language or that the skill is intentionally limited to a Chinese-only audience. The policy requires flagging language or locale constraints when they are imposed without opt-in or clear justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The delete_customer function removes a customer record and persists the change to customers.json, making it a destructive operation. Although there is a success message after deletion, there is no prior confirmation step or explicit warning in the function docstring/comments that data will be permanently removed.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module docstring and user-facing descriptions are written entirely in Chinese, and there is no indication that the skill supports alternative languages or that Chinese is an explicit opt-in or required regional constraint. Under the policy rule, forcing a specific language without user choice is a natural-language locale 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 docstring is entirely in Chinese and presents the skill as a customer-management utility without offering any language choice or documenting a locale-specific constraint. This can violate language/locale policy because the skill appears to assume Chinese-language operation for all users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The file presents all user-facing guidance in Chinese and does not indicate that the language is optional, user-selected, or required for a specific region. This can be a natural-language policy issue when a skill effectively forces a language or locale without opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The module name, description, docstrings, and user-facing messages are all presented in Chinese, which effectively forces a specific language experience. The file does not indicate that this locale restriction is optional, user-selected, or justified as a region-specific tool.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file’s user-facing natural-language description is entirely in Chinese and presents the skill as Chinese-language only. Under the policy, language or locale restrictions should either be optional for the user or clearly justified as region-specific; neither is stated here.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.