T09 · Insecure Skill Coding Practices
- Location
assets/webmcp-bridge.js:172- Finding
Unauthenticated Cross-Origin WebMCP Tool Execution
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is mostly coherent for adding WebMCP support, but its browser bridge and examples expose agent-callable web actions with weak origin, consent, and data-handling safeguards.
Install only if you are prepared to harden it before exposing it to users: pin and verify the CLI package, add strict postMessage origin/source checks and non-wildcard replies, require authorization and confirmation for mutating tools, avoid storing sensitive drafts in localStorage, and validate generator inputs before running the scripts.
assets/webmcp-bridge.js:172Unauthenticated Cross-Origin WebMCP Tool Execution
SKILL.md:127Unpinned and Ambiguous Third-Party CLI Execution
scripts/add-tool.sh:7Path Traversal and File Overwrite in Tool Generator
templates/tools/form.ts:98Plaintext Persistence, Disclosure, and Logging of Arbitrary Form Data
The bridge accepts postMessage events based only on a webmcp: type prefix and explicitly leaves origin validation commented out. That allows any frame or window able to message this page to invoke registered tools, query status, or influence bridge behavior, which can become a powerful cross-origin capability exposure depending on what tools the page registers.
The trigger list includes broad phrases like ai agent web, agent accessible, and tool registration, which are generic enough to match many unrelated requests. This can cause unintended invocation of a skill that has Write, Edit, and Bash permissions, increasing the chance an agent activates higher-risk functionality in the wrong context.
The documentation instructs users to run npx webmcp without pinning a specific package version, which can cause execution of whatever version is currently published at install time. In a security-sensitive setup tool, this creates a supply-chain risk because a compromised or malicious future release could be fetched and executed automatically on the user's machine.
The markdown explicitly presents mutating tool capabilities like addToCart and updateProfile but does not warn that these operations can change application state or user data. In the context of an AI-agent-accessible web interface, omission of mutation warnings can normalize unsafe patterns and lead operators or downstream implementers to expose state-changing tools without confirmation, authorization, or audit controls.
This JavaScript bridge sets up cross-frame message handling and immediately notifies the parent window that the bridge is ready, later exposing session identifiers and tool metadata through postMessage. Although the file has technical comments, it does not provide any user-facing warning, confirmation, or disclosure that browser context data will be shared across frames.
The message handler exposes remote dispatch of page-registered tools to any messaging peer, not just a trusted embedding context. In this skill, tools are the primary capability surface, so unrestricted cross-frame invocation can let an untrusted frame trigger sensitive application actions through legitimate handlers.
The bridge sends responses, tool events, session identifiers, and tool inventories with targetOrigin='*', which can disclose internal capability metadata to whatever window is on the other side of the reference. In the WebMCP context, tool names and status information may reveal privileged actions or integration details that aid abuse of the broader messaging interface.
The file exposes state-changing tools such as cart item removal, navigation, and form submission that can be invoked by an AI agent through navigator.modelContext with no built-in confirmation, authorization gate, or user-approval step. In a WebMCP context, this is more dangerous because the entire purpose is to let agents drive web actions, so unsafe-by-default tool registration can enable unintended or manipulated actions that affect user state.
The clearCart tool performs an irreversible state-reset operation by emptying the entire cart, but the implementation contains no confirmation prompt and no user-facing disclosure beyond the returned success message after the action occurs. For a destructive operation in a code file, this lacks a prior warning or other explicit disclosure mechanism in the code shown.
The clearChat tool performs a destructive action with no built-in confirmation, warning, or safeguard. In an AI-agent-accessible web app, a mistaken, coerced, or malicious tool invocation could irreversibly remove conversation history and disrupt auditing, user context, or evidence needed for recovery.
The tool is annotated as read-only even though it initiates an export operation that can create or write a file. In an agent-tooling ecosystem, incorrect mutability metadata can cause a planner or policy layer to permit this action in contexts where only non-mutating tools should be allowed, increasing the chance of unintended data exfiltration or writes.
The removeWidget tool deletes a dashboard widget by dispatching a remove action, but the implementation contains no confirmation prompt and no explicit warning comment or docstring about the destructive effect. Although it returns a success message after completion, that is not a pre-action user disclosure for a potentially irreversible operation.
The tool stores arbitrary form draft contents in localStorage, which is readable by any script running on the same origin and persists across browser sessions. If forms contain sensitive fields such as personal data, tokens, or financial details, this increases exposure in the event of XSS or shared-device access, and there is no built-in disclosure, consent, or field-level restriction.
When clearDraft is true, the tool removes saved draft data from localStorage, which is a destructive operation affecting user data. The code performs the deletion silently without confirmation or a prior warning that stored draft data will be erased.
The file's user-facing natural-language descriptions and comments are consistently in Italian, including the tool description and parameter descriptions. This can violate a language/locale policy when the skill forces a specific language without user opt-in and no region-specific justification is provided.
The exported tool metadata that downstream users or agents may surface is entirely in Italian, such as the main description and parameter descriptions. Because no language choice or locale limitation is declared, this is a natural-language policy concern under the language/locale rule.
The file’s instructional comments are written only in Italian, telling the user how to include the script, without offering an alternative language or indicating that the skill is intended for an Italian-only audience. This can violate language/locale policy when no user opt-in or documented regional justification is provided.
This shell script includes a natural-language description in Italian ("Aggiunge un nuovo tool WebMCP") while the rest of the usage output is in English, and there is no opt-in or documented locale constraint. Under the policy rule, forcing a specific language without user choice is a natural-language locale violation.
The file's natural-language descriptions and user-facing messages are written exclusively in Italian, with no indication that the language is configurable or chosen by the user. This can violate language/locale policy when a skill imposes a specific language without opt-in or documented locale constraints.
The exportChat tool writes chat history to a file without any explicit privacy or data-handling warning. Because chat transcripts may contain sensitive prompts, credentials, or personal data, silent export increases the risk of unintentional disclosure, especially in a tool surface exposed to autonomous agents.
Comments, descriptions, parameter help text, and user-facing messages are consistently written in Italian. This imposes a specific language on users without any opt-in or documented justification for the locale constraint.
No suspicious patterns detected.