Back to skill

Security audit

Frappe MCP

Security checks for vulnerabilities and agentic risk

Overview

This skill is an ERPNext automation pack, but it gives agents broad authority to create, change, submit, delete, export, and run custom methods on business records with weak scoping and confirmation controls.

Install only for a tightly controlled ERPNext account with least-privilege roles. Require human review before create, update, submit, cancel, delete, export, payment, stock, and custom-method operations, and avoid enabling the generic_task or bulk_operation workflows unless the runtime enforces DocType allowlists, field/method allowlists, non-empty filters, dry runs, audit logs, and confirmation gates.

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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
definitions/generic_task.json:55
Finding
Unrestricted Generic ERP Operations and Arbitrary Document Method Invocation<![CDATA[ ## Vulnerability Details **File Location**: `definitions/generic_task.json`, lines 8-19, 55-60, 105-143, 172-211, and 234-239 **Vulnerability Type**: Unrestricted privileged operations and user-controlled method invocation **Risk Level**: High ### Vulnerable Code Broad natural-language phrases can activate the generic workflow: ```json "triggers": [ "do something", "handle this", "custom task", "general task", "process", "execute", "run report", "check status", "update record", "bulk operation", "anything else", "other task" ] ``` The workflow exposes consequential actions against a user-selected DocType: ```json "action": { "type": "string", "enum": [ "create", "read", "update", "delete", "list", "search", "submit", "cancel", "custom" ], "description": "Action to perform" } ``` Update and deletion operations accept the target DocType, record name, and replacement data directly from the execution context: ```json "if_action_is_update": { "steps": [ { "step": "get_document", "tool": "get_document", "arguments": { "doctype": "${target_doctype}", "name": "${target_name}" } }, { "step": "update_document", "tool": "update_document", "arguments": { "doctype": "${target_doctype}", "name": "${target_name}", "data": "${data}" } } ] }, "if_action_is_delete": { "steps": [ { "step": "get_document", "tool": "get_document", "arguments": { "doctype": "${target_doctype}", "name": "${target_name}" } }, { "step": "delete_document", "tool": "delete_document", "arguments": { "doctype": "${target_doctype}", "name": "${target_name}" } } ] } ``` Submit, cancel, and arbitrary document-method operations are similarly exposed: ```json "if_action_is_submit": { "steps": [ { "step": "submi ...[truncated 3688 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `custom` and `run_doc_method` from the generic workflow unless there is a documented business requirement. 2. If custom methods are necessary, enforce a server-side allowlist of permitted DocTypes, methods, and argument schemas. Deny all unrecognized combinations. 3. Define separate narrowly scoped workflows for read, update, submit, cancel, and administrative operations rather than routing them through a universal dispatcher. 4. Require explicit, contextual confirmation before update, delete, submit, cancel, payment, stock, and custom-method operations. 5. Enforce authorization in the MCP tool and ERPNext server layers before every operation. Do not treat JSON guardrail flags as security controls unless the loader demonstrably enforces them. 6. Run the Agent under a dedicated least-privilege ERPNext account rather than an Administrator-equivalent identity. 7. Restrict generic triggers to explicit phrases so ordinary words such as “process” or “execute” cannot activate the workflow accidentally. 8. Log the authenticated user, target DocType, target record, method, sanitized arguments, confirmation event, and operation result in an immutable audit trail. 9. Add automated tests proving that unauthorized DocTypes and methods are rejected even when the Agent supplies syntactically valid requests. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
definitions/bulk_operation.json:82
Finding
Unsafe Bulk Deletion and Unrestricted Record Export<![CDATA[ ## Vulnerability Details **File Location**: `definitions/bulk_operation.json`, lines 20-54, 82-109, and 114-118 **Vulnerability Type**: Insufficient scoping and validation of destructive bulk operations **Risk Level**: High ### Vulnerable Code Only the operation and DocType are mandatory. The filter and exported-field selections remain optional and unconstrained: ```json "filters": { "type": "object", "description": "Filters for export or delete" }, "fields": { "type": "array", "description": "Fields to export" }, "update_existing": { "type": "boolean", "description": "Update existing documents on import", "default": false } }, "required": ["operation", "doctype"] ``` Bulk deletion executes whenever a filter object is provided, without requiring a non-empty or sufficiently selective filter: ```json { "step": "execute_delete", "tool": "bulk_delete_documents", "condition": "operation == 'delete' and filters is provided", "arguments": { "doctype": "${doctype}", "filters": "${filters}" } } ``` Bulk export does not require filters or an allowlist of exportable fields: ```json { "step": "execute_export", "tool": "export_documents", "condition": "operation == 'export'", "arguments": { "doctype": "${doctype}", "filters": "${filters}", "fields": "${fields}" } } ``` The safeguards are only represented as declarative configuration: ```json "guardrails": { "max_batch_size": 1000, "require_confirmation_for_delete": true, "validate_data_first": true, "backup_before_delete": true } ``` ### Technical Analysis The schema allows any string as `doctype` and any object as `filters`. An empty object satisfies the object type and may be considered “provided” by the workflow condition. If the underlying MCP tool interprets an empty filter as matching all documents, the deletion operation can affect an entire DocType. The export path is similarly unrestricted. It runs without requiring filters and accep ...[truncated 1960 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Reject missing, null, empty, tautological, and insufficiently selective filters for destructive operations. 2. Require a dry-run step that returns the exact record identifiers and count before any bulk update or deletion. 3. Require explicit confirmation containing the DocType, filter summary, and affected-record count. 4. Enforce hard record limits in the underlying MCP tools, not only in JSON metadata. 5. Allowlist DocTypes eligible for bulk operations and separately allowlist fields eligible for export. 6. Require explicit filters for export and apply row-level and field-level authorization before returning data. 7. Ensure `backup_before_delete` is a mandatory verified workflow step. Abort if backup creation or verification fails. 8. Use transaction boundaries or resumable batch processing so partial failures cannot leave data in an inconsistent state. 9. Apply least-privilege ERPNext roles and prevent the Agent account from bulk-modifying or exporting sensitive administrative DocTypes. 10. Add tests for `{}`, omitted filters, wildcard-like filters, oversized batches, sensitive field requests, and confirmation bypass attempts. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
definitions/process_payment.json:43
Finding
Insufficient Validation of Payment Amounts, Parties, and References<![CDATA[ ## Vulnerability Details **File Location**: `definitions/process_payment.json`, lines 43-78, 83-117, and 124-127 **Vulnerability Type**: Inadequate financial transaction validation **Risk Level**: Medium ### Vulnerable Code The amount has no positive minimum, and several integrity-relevant fields are not required: ```json "party_type": { "type": "string", "enum": ["Customer", "Supplier"], "description": "Party type" }, "party": { "type": "string", "description": "Customer or Supplier name" }, "amount": { "type": "number", "description": "Payment amount" }, "reference_doctype": { "type": "string", "enum": [ "Sales Invoice", "Purchase Invoice", "Sales Order", "Purchase Order" ], "description": "Reference document type" }, "reference_name": { "type": "string", "description": "Reference document number" }, "payment_type": { "type": "string", "enum": ["Receive", "Pay"], "description": "Payment type" }, "mode_of_payment": { "type": "string", "description": "Mode of payment (Cash, Bank, etc.)" }, "transaction_date": { "type": "string", "description": "Payment date" } }, "required": ["party", "amount", "payment_type"] ``` A reference is fetched only when supplied, after which the user-provided amount is copied directly into the payment allocation: ```json { "step": "fetch_invoice", "tool": "get_document", "arguments": { "doctype": "${reference_doctype}", "name": "${reference_name}" }, "condition": "reference_name is provided" }, { "step": "get_schema", "tool": "get_doctype_meta", "arguments": { "doctype": "Payment Entry" } }, { "step": "create_payment", "tool": "create_document", "arguments": { "doctype": "Payment Entry", "data": { "payment_type": "${payment_type}", "party_type": "${party_type}", "party": "${party}", "amount": "${amount}", "mode_of_payment": "${mode_of_payment}", "transaction_date": "${transaction_date}", ...[truncated 2679 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add an exclusive positive minimum to `amount` and define an appropriate maximum or approval threshold. 2. Require `party_type`, `party`, `reference_doctype`, `reference_name`, `payment_type`, `mode_of_payment`, and `transaction_date` for referenced payment workflows. 3. Create a separate explicitly approved workflow if unallocated payments are a legitimate requirement. 4. Verify that the referenced document exists, is submitted, belongs to the supplied party, has the correct company and currency, and has sufficient outstanding balance. 5. Enforce valid combinations of party type, payment direction, and reference type. 6. Derive allocation limits from the fetched ERP record rather than trusting the user-provided amount. 7. Validate transaction dates against accounting periods and company policy. 8. Require explicit confirmation showing party, direction, reference, amount, currency, and payment mode before creating or submitting the payment. 9. Enforce all financial checks server-side in ERPNext or the MCP implementation so they cannot be bypassed by another Skill definition. 10. Add automated tests for negative amounts, zero amounts, overpayment, cross-party references, invalid direction combinations, closed periods, and missing references. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (26)

Missing User Warnings

High
Confidence
96% confidence
Finding
The skill advertises an end-to-end sales workflow that culminates in invoice creation and payment recording, but it provides no user-facing warning or explicit consent checkpoint for these irreversible or sensitive financial operations. In context, this makes the skill more dangerous because it combines broad activation with actions that can affect accounting records, receivables, and customer balances.

Vague Triggers

High
Confidence
98% confidence
Finding
The trigger list includes extremely generic phrases such as "do something," "handle this," "process," "execute," and "anything else," which can cause the skill to activate for unrelated user requests. Because this skill can perform powerful actions including create, update, delete, submit, cancel, and custom method execution, accidental invocation materially increases the risk of unintended data access or state-changing operations.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The sales workflow skills include creating sales orders, invoices, and a full quotation-to-payment workflow, all of which can affect transactional business records. The README presents these actions as routine examples but does not warn users that execution may create real ERP documents or trigger downstream financial process changes.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The `process_payment` skill records payment entries, which is a safety-critical financial action with potential accounting consequences. The markdown does not disclose this risk or advise users to verify amounts, counterparties, and environment before running the skill.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The markdown advertises a `bulk_operation` skill for `Bulk create/update/delete`, which includes potentially destructive changes to business data. The document does not provide any warning about data modification risk, confirmation requirements, reversibility, or the need for careful review before use.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger list is broad and generic for high-risk capabilities such as bulk create, update, delete, import, and export. This increases the chance of unintended or ambiguous invocation, which is especially dangerous because the workflow can perform destructive actions or mass data exfiltration across arbitrary DocTypes if the agent routes a loosely matching user request to this skill.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The trigger phrases are broad, generic, and map to a high-impact workflow that creates quotations, orders, invoices, and payments. This increases the chance of accidental activation from ordinary user language, which is especially dangerous because the workflow performs financially consequential actions rather than a read-only task.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
The workflow uses `${total}` and `${invoice_name}` in the payment step without any documented prior step that reliably derives or binds those values. In an automation that records payments, unresolved or incorrectly resolved placeholders can lead to wrong payment amounts, misapplied payments, or failures that still create partial business records.

Vague Triggers

Medium
Confidence
90% confidence
Finding
This manifest defines generic triggers such as "create customer", "add customer", and especially "new customer" without any narrowing context or exclusion conditions. In a manifest file, such broad activation phrases can cause unintended invocation when users discuss customer onboarding generally rather than explicitly invoking this skill.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The trigger phrase "bill customer" is broad and can match common conversational business requests that may not specifically mean creating a Sales Invoice in this system. In an automation context tied to document creation, ambiguous triggering can cause unintended invocation of an action-capable skill and lead to accidental invoice generation or billing workflows being started without sufficient user intent clarity.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrases are generic action terms like 'create item', 'add item', and 'new product', which can cause the skill to activate from ordinary inventory-related conversation without strong contextual confirmation. Because the workflow performs a state-changing operation that creates a new Item record, unintended invocation could lead to unauthorized or accidental data creation in the inventory system.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill performs a write operation that creates a persistent Item document but does not declare any user-facing warning, confirmation, or disclosure in the manifest. In an agent environment, this increases the risk that a user or upstream prompt causes silent inventory changes, especially since the skill can set pricing, warehouse, and stock-related fields with business impact.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The description omits that the skill creates a persistent CRM record and processes personal contact information such as name, email, and phone numbers. This reduces user and operator awareness of the data-handling and write side effects, increasing the chance of accidental use and inappropriate disclosure or storage of PII.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger phrases are generic and action-oriented, so the skill may be invoked in response to common user language without enough confirmation that the user intended to create a CRM record. Because the workflow writes personal contact data directly into the CRM, unintended activation could create unauthorized or erroneous leads containing PII.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrases are generic enough to match common natural-language requests such as 'create project' or 'start project', which can cause this skill to activate in situations where the user did not intend to invoke it. Because the workflow directly creates a Project document with user-supplied fields and minimal guardrails, accidental invocation could lead to unwanted record creation, data clutter, or misuse of backend write capabilities.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The trigger phrases are broad enough to match ordinary procurement requests and may cause this skill to activate in situations where the user did not explicitly intend to create a purchase order. Because the workflow can create a purchasing document and is wired to business tools, accidental invocation could lead to unauthorized or premature procurement actions if additional confirmation is not enforced at runtime.

Vague Triggers

Medium
Confidence
82% confidence
Finding
This JSON manifest applies to SQP-1, and the description 'Create a sales quotation for a customer with items' is a broad natural-language capability statement without any explicit trigger phrases, scope limits, or exclusion conditions. That ambiguity can cause unintended invocation for generic sales or customer-related requests rather than a clearly bounded action.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest declares a `require_customer_credit_check` guardrail, but the workflow never performs any credit-check step before calling `doc.create`. This creates a business-logic gap where users can generate quotations for customers without the intended validation, undermining policy enforcement and potentially enabling risky or unauthorized commercial actions.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The trigger set includes generic business phrases such as "create sales order" and "process customer order," which can easily match ordinary user requests and cause the skill to activate in situations broader than intended. Because this skill creates transactional ERP records, overly broad activation increases the risk of unintended order creation, especially when combined with direct insertion of user-provided item data into the Sales Order document.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The description says only 'Process payment against a sales invoice or sales order' and does not clearly disclose that the skill creates a Payment Entry that changes financial records. This can mislead users or orchestrators about the sensitivity of the action, reducing caution around a workflow that writes accounting data.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The trigger phrases are generic enough to match ordinary conversational requests about payments, increasing the chance the skill activates in situations where the user did not intend to create a financial record. In this skill, activation leads directly to creation of a Payment Entry, so accidental invocation could modify accounting data or initiate a payable/receivable workflow without sufficient user awareness.

Vague Triggers

Medium
Confidence
97% confidence
Finding
The trigger list includes very generic phrases such as 'search', 'find', and 'lookup', which are likely to match many ordinary user requests unrelated to this specific skill. This can cause the skill to activate too broadly and invoke document-search capabilities in unintended contexts, increasing the chance of unnecessary data exposure or inappropriate tool use.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The trigger set is broad enough to activate on routine inventory-related phrases like 'stock entry' or 'stock transfer' without clearly establishing whether the user wants an action performed versus general information or review. In a skill that can create business records and potentially submit them, ambiguous activation increases the chance of unintended stock movements or draft creation from ordinary conversation.

Vague Triggers

Low
Confidence
84% confidence
Finding
The trigger set contains generic invoice-related phrases without explicit scoping rules, exclusions, or confirmation boundaries, which makes it unclear when this skill should activate versus when the user may be asking for advice, status, or another billing action. Because this skill can create financial records, ambiguous invocation increases the risk of unintended operational actions, especially in assistants that auto-route based on natural language triggers.

Vague Triggers

Low
Confidence
84% confidence
Finding
This manifest file defines activation triggers such as "add supplier" and "new vendor" without any negative examples or contextual constraints. Those phrases are relatively generic in business conversation and could cause unintended invocation when a user is discussing suppliers rather than explicitly requesting record creation.

Static analysis

No suspicious patterns detected.