Back to skill

Security audit

WebMCP

Security checks for vulnerabilities and agentic risk

Overview

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.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
assets/webmcp-bridge.js:172
Finding

Unauthenticated Cross-Origin WebMCP Tool Execution

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:127
Finding

Unpinned and Ambiguous Third-Party CLI Execution

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/add-tool.sh:7
Finding

Path Traversal and File Overwrite in Tool Generator

Content
View full analysis
[target-dir]" echo "" echo "Example:" echo " add-tool.sh searchProducts" exit 1 fi TARGET_DIR="$(cd "$TARGET_DIR" && pwd)" TOOLS_DIR="$TARGET_DIR/tools" echo "🔧 Creating tool: $TOOL_NAME" mkdir -p "$TOOLS_DIR" # Create tool file cat > "$TOOLS_DIR/$TOOL_NAME.ts" << EOF ``` The same unvalidated value is used for the test file: ```bash # Create test file cat > "$TOOLS_DIR/$TOOL_NAME.test.ts" << EOF ``` ### Technical Analysis `TOOL_NAME` is accepted directly from the first command-line argument and concatenated into output paths. The script checks only that the value is nonempty. It does not reject path separators, `..` components, absolute paths, shell-invalid TypeScript identifiers, or pre-existing destination files. Shell quoting prevents ordinary shell metacharacters inside `TOOL_NAME` from becoming separate shell commands, but it does not prevent filesystem path traversal. A value containing `../` can resolve outside the intended `tools` directory. Redirection with `>` silently truncates an existing file. The name is also interpolated into generated TypeScript source, which can produce malformed or attacker-influenced source content. The confirmed direct security consequence is unauthorized file placement or overwrite within locations writable by the invoking user. ### Attack Path 1. An attacker, automation input, or unsafe agent-generated argument supplies a name containing traversal components, such as `../../src/target`. 2. The script constructs the path: ```text /tools/../../src/target.ts ``` 3. The operating system normalizes the traversal and resolves it outside `/tools`. 4. If the ...[truncated 920 chars]
Remediation
View remediation
&2 exit 1 fi ``` 2. Explicitly reject `/`, `\`, `..`, leading dots, control characters, and absolute paths. 3. Canonicalize each destination and verify that it remains beneath the canonical `TOOLS_DIR`. 4. Refuse to overwrite existing files by default, using an existence check or noclobber behavior. 5. Require an explicit `--force` option for intentional replacement. 6. Escape or structurally generate TypeScript identifiers and string literals rather than directly interpolating unchecked values. 7. Add tests for traversal names, absolute paths, Unicode separators, invalid identifiers, and collisions with existing files. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
templates/tools/form.ts:98
Finding

Plaintext Persistence, Disclosure, and Logging of Arbitrary Form Data

Content
View full analysis
= {}; for (const field of fields) { // Validazione campi required if (field.required && (field.value === undefined || field.value === null || field.value === '' || (Array.isArray(field.value) && field.value.length === 0))) { validationErrors.push({ field: field.name, message: `Il campo ${field.name} è obbligatorio`, code: 'required' }); continue; } // Salva dato processato processedData[field.name] = field.value; } // Salva bozza if (action === 'save_draft') { // In un'app reale, salveresti su localStorage o backend localStorage.setItem(`form_draft_${formId}`, JSON.stringify(processedData)); return { success: true, formId, data: processedData, message: 'Bozza salvata con successo' }; } // Invio form (azione di default) // In un'app reale, faresti una chiamata API qui console.log('[submitForm] Dati inviati:', processedData); ``` The load operation returns the entire stored object: ```typescript const draftData = localStorage.getItem(`form_draft_${formId}`); if (!draftData) { return { success: false, formId, message: 'Nessuna bozza trovata' }; } return { success: true, formId, data: JSON.parse(draftData), message: 'Bozza caricata con successo' }; ``` ### Technical Analysis The form tool accepts arbitrary field names and values and copies all of them into `processedData`. For draft operations, the complete object is serialized into `localStorage` without field classification, encryption, expiration, user scoping, or a sensitive-field denylist. For ordinary submission, the same object is written to the browser cons ...[truncated 1851 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (21)

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.