Back to skill

Security audit

After-sales Service

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its after-sales purpose, but its OKKI CRM sync has public mutation endpoints and unsafe Python execution patterns that need manual review before use.

Install only after reviewing and fixing the OKKI integration. At minimum, require authentication and authorization on all HTTP routes, add explicit confirmation/privacy notices before syncing to OKKI, remove dynamic Python source generation, use secure temporary-file handling or stdin/JSON IPC, and avoid exposing raw sync logs or error details publicly.

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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
api/routes/okki_routes.js:12
Finding

Unauthenticated HTTP Endpoints Can Modify OKKI CRM Records

Content
View full analysis
{ try { const complaintId = req.params.id; if (!complaintId) { return res.status(400).json({ success: false, message: 'Complaint ID cannot be empty' }); } const result = await okkiSyncController.syncComplaintToOKKI(complaintId); if (result.success) { res.status(200).json(result); } else { res.status(400).json(result); } } catch (error) { console.error('Failed to synchronize complaint to OKKI:', error); res.status(500).json({ success: false, message: 'Server error', error: error.message }); } }); /** * @route POST /api/after-sales/repeat-order/:id/sync-okki * @desc Synchronize a repeat-order quotation to OKKI * @access Public */ router.post('/repeat-order/:id/sync-okki', async (req, res) => { try { const repeatOrderId = req.params.id; if (!repeatOrderId) { return res.status(400).json({ success: false, message: 'Repeat-order ID cannot be empty' }); } const result = await okkiSyncController.syncRepeatOrderToOKKI(repeatOrderId); if (result.success) { res.status(200).json(result); } else { res.status(400).json(result); } } catch (error) { console.error('Failed to synchronize repeat order to OKKI:', error); res.status(500).json({ success: false, message: 'Server error', error: error.message }); } }); ``` ### Technical Analysis Both POST routes are explicitly documented as public and invoke operations that create follow-up records in the O ...[truncated 1726 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
api/routes/okki_routes.js:80
Finding

Public Synchronization Log Endpoints Expose Internal CRM and Error Information

Content
View full analysis
{ try { const id = req.params.id; if (!id) { return res.status(400).json({ success: false, message: 'ID cannot be empty' }); } const log = OkkiSyncLog.getById(id); if (!log) { return res.status(404).json({ success: false, message: 'Synchronization record not found', id }); } res.status(200).json({ success: true, data: log.toObject() }); } catch (error) { console.error('Failed to retrieve synchronization status:', error); res.status(500).json({ success: false, message: 'Server error', error: error.message }); } }); router.get('/okki/logs', async (req, res) => { try { const limit = parseInt(req.query.limit) || 20; const logs = OkkiSyncLog.getRecent(limit); res.status(200).json({ success: true, count: logs.length, data: logs.map(log => log.toObject()) }); } catch (error) { console.error('Failed to retrieve synchronization logs:', error); res.status(500).json({ success: false, message: 'Server error', error: error.message }); } }); router.get('/okki/logs/failed', async (req, res) => { try { const logs = OkkiSyncLog.getFailed(); res.status(200).json({ success: true, count: logs.length, data: logs.map(log => log.toObject()) }); } catch (error) { console.error('Failed to retrieve failed logs:', error); res.status(500).json({ success: false, message: 'Server er ...[truncated 2740 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
api/controllers/okki_sync_controller.js:218
Finding

Dynamic Python Source Generation Allows Code Injection

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
api/controllers/okki_sync_controller.js:243
Finding

Predictable Shared Temporary Python File Enables Symlink Attacks and Data Leakage

Content
View full analysis
.py` as a symbolic link to a file writable by the service account. 3. The application calls `fs.writeFileSync` without exclusive creation. 4. Node.js follows the symbolic link and overwrites the target file with generated Python. 5. Alternatively, the attacker forces Python execution to fail. 6. Because cleanup is not in a `finally` block, the generated script remains in `/tmp`. 7. The attacker reads the retained file if its permissions allow access. ...[truncated 620 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
api/controllers/okki_sync_controller.js:321
Finding

Incorrect Model Import Can Report Successful CRM Writes as Failures and Cause Duplicates

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (36)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

该代码块的核心功能是“分析报表/分析接口”,与声明中的“售后管理技能”只部分重合。声明提到的分析报表功能与代码一致,但其余关键能力如投诉管理、返单报价、满意度调查、OKKI CRM 同步均未在代码中体现。相反,代码新增了客户风险分析和产品质量分析等声明未明确说明的分析能力。因此描述不能准确代表该代码块的实际行为,属于明显的部分不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

该代码块的核心功能与“OKKI CRM 同步”这一部分声明一致:会根据客户 ID/名称搜索 OKKI 公司,调用 CLI/Python 客户端创建售后跟进记录,并写入同步日志。但声明描述的是一个更完整的“售后管理技能”,包括客户投诉管理、返单报价、满意度调查、分析报表和 CRM 同步。实际代码仅覆盖其中的同步子功能,而且投诉/返单数据还是通过本地模拟函数获取,没有体现新增、编辑、查询、流程处理等完整管理能力,也没有任何满意度调查或分析报表逻辑。因此描述明显宽于代码实际行为,存在功能性不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding

声明描述的是一个较完整的售后管理技能,涵盖管理、报价、调查、报表以及 CRM 同步。但给出的代码块仅是一个命令行分析报表工具,主要职责是调用 analytics_api 获取各类分析结果并输出展示。它没有显示任何投诉工单管理、返单报价生成、满意度调查采集/发起、或 OKKI CRM 同步逻辑。相反,代码中明确包含了客户风险分析和产品质量分析这两项未在声明中提到的能力。虽然“分析报表”部分与声明一致,但整体声明与实际代码能力范围和重点存在明显偏差,因此应判定为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

从代码内容看,核心功能非常聚焦:通过 CLI 调用 controller 将投诉或返单记录同步到 OKKI CRM,并读取同步日志查看状态、最近记录和失败记录。这与声明中的“OKKI CRM 同步功能”以及部分“投诉/返单”场景一致,但远不足以支撑完整的“售后管理技能”描述。声明中提到的满意度调查、分析报表,在该代码中完全没有体现;所谓客户投诉管理和返单报价管理,也没有看到创建、编辑、分配、查询、统计等管理能力,只有针对现有记录的同步与日志查看。此外,声明的 Triggers 为空,但该代码实际提供了明确的 CLI 命令触发入口。综合来看,代码实际行为是“OKKI 同步及同步日志查询工具”,比声明范围更窄,且触发方式存在未声明内容,因此应判定为描述与行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

该代码与声明存在明显的描述-行为不一致。代码的核心用途是“分析报表模型”,这一点与声明中的“分析报表”部分一致;但声明还强调投诉管理、返单报价、满意度调查和 OKKI CRM 同步,这些在代码中都没有实现。代码只对本地 mockData 进行过滤、聚合和统计,导出若干分析函数,属于报表/分析层,而不是完整的售后管理与系统同步技能。因此应判定为存在不匹配,主要原因是声明覆盖了多个未实现的关键能力。

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node cli/after_sales_cli.js <module> <command> [options]

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The fallback path dynamically generates Python source code from application data, writes it to /tmp, and executes it. User-controlled fields such as description, notes, or other record content are embedded into Python code with insufficient escaping, so crafted input can break out of the string literal and achieve arbitrary Python code execution; the predictable /tmp filename pattern also adds race/symlink risk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
78% confidence
Finding

The skill documents use of environment variables for OKKI paths but does not declare any tool scope or permissions boundary. In an agent setting, missing explicit capability declarations weakens reviewability and can allow unintended environment access assumptions when the skill is executed or integrated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill advertises automatic synchronization of complaint and order-related records to an external CRM without clearly warning that customer data may be transmitted outside the local system. This can lead to unintentional disclosure of personal or commercially sensitive data, especially if operators assume the skill is local-only.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This file’s natural-language interface documentation, function descriptions, and parameter notes are entirely Chinese-language. Under the policy, forcing a specific language without offering choice or documenting a justified locale constraint is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest describes after-sales management with OKKI CRM synchronization, which justifies CRM API interaction, but this file implements that by spawning local Python interpreters and external scripts using child_process. Launching subprocesses is a materially broader capability than ordinary data synchronization and is not justified by the stated business purpose alone.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The route documentation marks the endpoint as public and describes syncing complaint data to OKKI, which implies transmitting business records to an external system. In this file there is no user-facing disclosure, confirmation, or warning about that outbound data transfer before the sync operation is invoked.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The complaint OKKI sync endpoint is explicitly documented as public and the route implementation shows no authentication or authorization checks before triggering synchronization. That allows any caller who can reach the endpoint to initiate external business-data transfer or operational actions, creating risks of unauthorized data propagation, abuse, and integrity issues.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The repeat-order synchronization route is also exposed without any visible access control while performing a sensitive business operation against an external CRM. An attacker could invoke syncs for arbitrary IDs, potentially causing unauthorized disclosure of commercial data, duplicate sync activity, or manipulation of downstream records.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

This endpoint publicly exposes an operation to sync repeat-order quotation data to OKKI, which is a network/data-sharing action. The file contains no visible warning, confirmation prompt, or user-facing notice describing that invoking the route will transmit data to an external service.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The status and log endpoints expose internal synchronization records and are documented as public, with no route-level access controls present. Public access to operational logs can leak internal identifiers, sync outcomes, timestamps, errors, and business workflow details that help attackers enumerate records or target downstream systems.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The complaint section is documented and exposed as full complaint management, but getAllComplaints() always returns a static in-memory mock array instead of loading the saved JSON file. As a result, createComplaint, updateComplaint, recordSatisfaction, and deleteComplaint write to disk while all read/list/get/stat operations continue to operate on unrelated mock data, which materially diverges from the stated management behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The repeat-order module presents create/list/get/update management functionality, yet getAllRepeatOrders() returns fixed mock data rather than the saved repeat_orders.json contents. This means writes performed by createRepeatOrder and updateRepeatOrder are not reflected in later reads, so the implemented behavior does not match the claimed management capability.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The complaint delete CLI command directly invokes deleteComplaint, which removes a complaint record and persists the change, but the flow provides no confirmation prompt before the irreversible action. Although a success message is printed after deletion, there is no prior user-facing warning or safeguard around the destructive operation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The OKKI sync commands trigger network-backed synchronization of complaint or repeat-order data to an external system, and the command descriptions do not warn that customer identifiers and related business records will be transmitted. Runtime output indicates syncing has started, but that disclosure occurs only after invocation rather than as an upfront warning to the user.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This is a code file, so SQP-2 applies to safety-relevant operations such as network calls. The commands sync-complaint and sync-repeat-order invoke controller methods that synchronize records to OKKI, but the help text and command flow do not warn users that invoking these commands sends complaint/order and customer-related data to an external CRM system.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

This JavaScript file contains natural-language descriptions and inline comments in Chinese, but there is no indication that the skill is limited to Chinese-speaking users or that another language option is available. Under the policy, forcing a specific language without opt-in or documented justification is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The remove and clear functions delete persisted log data and immediately overwrite the backing JSON file via saveToFile(). While the file contains comments about purpose, there is no confirmation prompt, user-facing log/print, or explicit warning that these operations irreversibly remove stored sync history.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

User-visible help and status messages are presented in Chinese throughout the script, but there is no opt-in, fallback, or explanation that the skill is intentionally restricted to a Chinese-speaking context. This creates a natural-language policy concern because it forces a specific language without user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This JavaScript file contains natural-language comments and extensive user-facing console/report text entirely in Chinese, indicating the skill's interaction language is fixed rather than user-selectable. The policy for SQP-3 applies to all file types and flags language/locale constraints when the skill does not provide opt-in or a documented justification.

Content

No source excerpt is available for this finding.