Back to skill

Security audit

Volkern MCP Server

Security checks for vulnerabilities and agentic risk

Overview

This CRM connector is mostly coherent, but it can change live customer records and send messages, and the code has a confirmed URL path handling weakness.

Install only with a least-privilege Volkern API key and treat the tools as live CRM actions. Require human confirmation before sends, cancellations, record updates, catalog changes, or task completion, and prefer a pinned package version. The publisher should validate and encode URL path IDs before this is used with sensitive production data.

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

T09 · Insecure Skill Coding Practices

Warning
Location
src/index.ts:588
Finding
Unvalidated Identifiers Permit Authenticated API Path Manipulation## Vulnerability Details **File Location**: `src/index.ts:588-594` and equivalent identifier interpolation at `src/index.ts:634-640`, `src/index.ts:656-693` **Vulnerability Type**: Improper validation and encoding of URL path segments **Risk Level**: Medium ### Vulnerable Code ```typescript case "volkern_get_lead": return volkernRequest(`/leads/${args.leadId}`); case "volkern_create_lead": return volkernRequest("/leads", "POST", args); case "volkern_update_lead": { const { leadId, ...data } = args; return volkernRequest(`/leads/${leadId}`, "PATCH", data); } ``` The same pattern is used for catalog items, services, tasks, interactions, and notes: ```typescript case "volkern_get_catalogo_item": return volkernRequest(`/catalogo/${args.itemId}`); case "volkern_update_catalogo_item": { const { itemId, ...data } = args; return volkernRequest(`/catalogo/${itemId}`, "PATCH", data); } case "volkern_get_servicio": return volkernRequest(`/servicios/${args.servicioId}`); case "volkern_create_task": { const { leadId, ...taskData } = args; return volkernRequest(`/leads/${leadId}/tasks`, "POST", taskData); } case "volkern_list_tasks": return volkernRequest(`/leads/${args.leadId}/tasks`); case "volkern_complete_task": return volkernRequest(`/tasks/${args.taskId}`, "PATCH", { completada: true }); case "volkern_list_interactions": return volkernRequest(`/leads/${args.leadId}/interactions`); case "volkern_create_interaction": { const { leadId, ...interactionData } = args; return volkernRequest(`/leads/${leadId}/interactions`, "POST", interactionData); } case "volkern_list_notes": return volkernRequest(`/leads/${args.leadId}/notes`); case "volkern_create_note": { const { leadId: noteLeadId, ...noteData } = args; return volkernRequest(`/leads/${noteLeadId}/notes`, "POST", noteData); } ``` The resulting request includes the configured bearer credent ...[truncated 3130 chars]
Remediation
## Remediation Suggestions 1. Validate every entity identifier before constructing an API path. Use the exact identifier grammar supported by Volkern rather than merely checking that the value is a string. 2. Reject identifiers containing path separators, traversal sequences, query delimiters, fragment delimiters, control characters, or encoded variants of those values. 3. Encode each validated path segment with `encodeURIComponent` before interpolation. 4. Centralize path construction to prevent future handlers from bypassing validation. ```typescript function encodeEntityId(value: unknown, fieldName: string): string { if (typeof value !== "string") { throw new Error(`${fieldName} must be a string`); } // Replace this expression with Volkern's exact documented CUID grammar. if (!/^c[a-z0-9]+$/i.test(value)) { throw new Error(`${fieldName} has an invalid format`); } return encodeURIComponent(value); } case "volkern_get_lead": { const leadId = encodeEntityId(args.leadId, "leadId"); return volkernRequest(`/leads/${leadId}`); } ``` 5. Apply the same protection to `leadId`, `itemId`, `servicioId`, `taskId`, and every future identifier used in a URL path. 6. Perform runtime argument validation in the request handler rather than relying only on MCP tool-schema declarations. 7. Add negative tests covering `/`, `../`, `?`, `#`, `%2f`, `%2e%2e`, backslashes, control characters, and mixed or double encoding. 8. Regenerate `dist/index.js` from the corrected TypeScript source and verify that the distributed code contains the same validation. 9. Continue enforcing server-side API authorization, tenant isolation, and per-object permission checks as a separate defense-in-depth boundary.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (22)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
There is a clear mismatch between the declared description and the actual code. The description presents a feature-rich CRM automation skill, but the provided code is effectively empty: a node shebang and an empty export in a TypeScript declaration file. No behavior supporting any of the declared CRM, messaging, sales, or authentication capabilities is present in this chunk.

Known Vulnerable Dependency: @modelcontextprotocol/sdk==0.5.0 — 1 advisory(ies): CVE-2025-66414 (Model Context Protocol (MCP) TypeScript SDK does not enable DNS rebinding protec)

High
Category
Supply Chain
Confidence
94% confidence
Finding
The lockfile pins @modelcontextprotocol/sdk to 0.5.0, which is flagged for CVE-2025-66414 involving missing DNS rebinding protections. For an MCP server, this is especially relevant because the SDK may expose local services or privileged tooling to network-originated requests; if deployed with HTTP transport or browser-accessible surfaces, an attacker could abuse rebinding to reach localhost-exposed capabilities.

Known Vulnerable Dependency: @modelcontextprotocol/sdk==0.5.0 — 1 advisory(ies): CVE-2025-66414 (Model Context Protocol (MCP) TypeScript SDK does not enable DNS rebinding protec)

High
Category
Supply Chain
Confidence
98% confidence
Finding
The package explicitly depends on `@modelcontextprotocol/sdk` `^0.5.0`, and the static finding cites a known high-severity advisory affecting 0.5.0 related to missing DNS rebinding protections. For an MCP server skill that may expose local or internal resources to an agent-connected server process, this context makes the issue more dangerous because DNS rebinding can let an attacker pivot browser or client-origin assumptions to reach unintended services.

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The helper sends request bodies and query data to the remote Volkern API using fetch with an authorization header, and the tools include lead, appointment, note, interaction, and messaging data that may contain personal or sensitive information. While the code has internal tool descriptions, there is no visible confirmation prompt or user-facing warning in this file that these inputs will be transmitted off-system to a third-party service.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding
The README recommends running the MCP server via `npx volkern-mcp-server` without pinning a specific version. This can cause clients to fetch and execute whatever package version is current at install/runtime, increasing supply-chain risk if a malicious or compromised release is published. Because this is an MCP server intended to run with API credentials and interact with external systems, the blast radius is higher than for a passive library.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documentation advertises tools that create, update, schedule, and send WhatsApp messages against a live CRM, but it does not warn users that these actions mutate external state or may contact real customers. In an agent context, missing confirmation/impact guidance can lead to unintended data changes, spam, scheduling mistakes, or unauthorized communications through normal use or prompt manipulation.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill supports numerous state-changing operations such as creating and updating leads, booking or canceling appointments, creating tasks, moving deals, and sending commercial documents, but it lacks a general warning or confirmation requirement for destructive or modifying actions. An agent could therefore perform unintended CRM mutations based on ambiguous prompts, causing operational errors, customer confusion, or data integrity issues.

Session Persistence

Medium
Category
Rogue Agent
Content
**Tool sequence**:
1. `VOLKERN_GET_LEAD` - Verify lead exists [Prerequisite]
2. `VOLKERN_CREATE_TASK` - Create task for the lead [Required]
3. `VOLKERN_LIST_TASKS` - Get lead's pending tasks [Optional]
4. `VOLKERN_COMPLETE_TASK` - Mark task as done [Optional]
Confidence
80% 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.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill enables sending WhatsApp messages, quotations, and contracts to external recipients, but it does not instruct the agent to obtain explicit user confirmation before initiating outbound communications. This creates a real risk of unintended contact, privacy exposure, accidental disclosure of sensitive commercial terms, or unauthorized customer-facing actions.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The helper sends request bodies and query parameters to an external Volkern API using a bearer token, and the tool set includes personally identifiable CRM data such as names, emails, phone numbers, messages, notes, and appointments. In this file there is no confirmation prompt and no user-facing warning that invoking these tools transmits user or lead data to a remote service.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
Many tool schemas require Spanish-only enum values and parameter semantics such as estado, canal, tipo, accion, and values like 'confirmar', 'cancelar', and 'reprogramar'. This imposes a specific language/locale on users and integrators without offering a language choice or documenting a justified region-specific constraint.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
Natural-language parameters and values such as estado, canal, confirmar, cancelar, reprogramar, and many descriptions are fixed in Spanish throughout the tool interface. The file does not indicate that Spanish is an intentional region-specific constraint or provide any user opt-in or alternative locale, which can violate language/locale policy expectations.

Known Vulnerable Dependency: esbuild==0.27.3 — 1 advisory(ies): GHSA-g7r4-m6w7-qqqr (esbuild allows arbitrary file read when running the development server on Window)

Low
Category
Supply Chain
Confidence
85% confidence
Finding
The lockfile includes esbuild 0.27.3, which has a low-severity advisory for arbitrary file read in the development server on Windows. In this package it appears only as a dev dependency via tsx, so the risk is mainly limited to developer workflows and would typically require use of the esbuild dev server in a vulnerable context rather than affecting normal production runtime.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"README.md"
  ],
  "dependencies": {
    "@modelcontextprotocol/sdk": "^0.5.0",
    "zod": "^3.23.8"
  },
  "devDependencies": {
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
],
  "dependencies": {
    "@modelcontextprotocol/sdk": "^0.5.0",
    "zod": "^3.23.8"
  },
  "devDependencies": {
    "@types/node": "^20.6.2",
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"zod": "^3.23.8"
  },
  "devDependencies": {
    "@types/node": "^20.6.2",
    "tsx": "^4.20.3",
    "typescript": "^5.9.3"
  }
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
},
  "devDependencies": {
    "@types/node": "^20.6.2",
    "tsx": "^4.20.3",
    "typescript": "^5.9.3"
  }
}
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"devDependencies": {
    "@types/node": "^20.6.2",
    "tsx": "^4.20.3",
    "typescript": "^5.9.3"
  }
}
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Missing User Warnings

Low
Confidence
80% confidence
Finding
The skill reads the VOLKERN_API_KEY environment variable to authenticate outbound API calls. While the code errors if the variable is missing, it does not provide any user-facing explanation that the skill accesses credentials from the environment.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
dist/index.js:8

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/index.ts:15