Back to skill

Security audit

Maton MCP Tools

Security checks for vulnerabilities and agentic risk

Overview

This Maton skill appears purpose-built for SaaS OAuth connection management, but it handles sensitive API/OAuth authority with some missing safeguards users should review before installing.

Review this before installing in a production Clawdbot gateway. Protect MATON_API_KEY like a password, avoid committing or syncing the config file, verify OAuth destinations before authorizing apps, and consider adding URL allowlisting plus confirmation prompts for connection deletion.

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
reference/maton-controller.ts:272
Finding

Unvalidated Remote OAuth URLs Are Opened in the Browser

Content
View full analysis

Vulnerability Details

File Location: reference/maton-backend.ts:317-325, reference/maton-controller.ts:272-280, and reference/maton-views.ts:137-160
Vulnerability Type: Unvalidated redirect target and unsafe external-window handling
Risk Level: Medium

Vulnerable Code

reference/maton-backend.ts:317-325:

typescript
respond(true, {
  success: true,
  connectionId: result.data?.connection_Id,
  oauthUrl: result.data?.url,
  message: result.data?.url
    ? "Complete the OAuth flow at the provided URL"
    : "Connection created",
});

reference/maton-controller.ts:272-280:

typescript
if (result.oauthUrl) {
  window.open(result.oauthUrl, "_blank");
  setState((prev) => ({
    ...prev,
    connectingApp: null,
    showAppPicker: false,
    success: "OAuth window opened. Complete the authorization flow.",
  }));
}

reference/maton-views.ts:137-160:

typescript
<a
  href="${url}"
  target="_blank"
  rel="noopener noreferrer"
  @click=${() => props.onOpenOAuthUrl(url)}
>
  Click here to authorize
</a>

...

<button
  class="btn small primary"
  @click=${() => window.open(url, "_blank")}
>
  Authorize
</button>

Technical Analysis

The gateway accepts the OAuth URL returned by the remote Maton API and forwards it to the browser without validating its scheme, hostname, port, embedded credentials, or intended OAuth destination. The UI then assigns that value to an anchor and passes it directly to window.open().

Although the anchor includes rel="noopener noreferrer", both the anchor click handler and the separate authorization button open the URL programmatically. These window.open() calls do not explicitly request noopener and noreferrer. The anchor also has a duplicate click action: its default navigation opens one page while props.onOpenOAuthUrl(url) may open another.

Exploitation requires an attacker to ...[truncated 1773 chars]

Remediation
View remediation

Remediation Suggestions

  1. Validate every OAuth URL on the backend before returning it to the browser:

    • Parse it with new URL().
    • Require the https: scheme.
    • Reject URLs containing embedded usernames or passwords.
    • Reject unexpected ports.
    • Enforce an explicit allowlist of approved Maton and OAuth-provider hostnames.
    • Compare normalized hostnames rather than using suffix or substring checks.
  2. Return an error instead of forwarding a URL that fails validation. Apply the same validation to URLs received from both connection-creation and connection-list endpoints.

  3. Add defense-in-depth validation in the UI before opening any external URL.

  4. Open approved URLs with explicit isolation:

typescript
const parsed = new URL(result.oauthUrl);
const popup = window.open(
  parsed.toString(),
  "_blank",
  "noopener,noreferrer",
);

if (popup) {
  popup.opener = null;
}
  1. Remove the anchor's duplicate programmatic click handler. Use either a properly isolated anchor or a validated window.open() call, but not both.

  2. Maintain the approved OAuth-host list centrally, document why each host is required, and add tests covering malformed URLs, non-HTTPS schemes, embedded credentials, deceptive subdomains, unexpected ports, and unapproved hosts.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (11)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `maton-backend.ts` | Gateway RPC handlers |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `maton-backend.ts` | Gateway RPC handlers |

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill clearly enables network-capable behavior by integrating with an external SaaS platform and documenting remote API usage, yet it does not declare any explicit tool scope such as permissions or allowed-tools. This weakens least-privilege controls and can cause the host agent to grant broader-than-expected network access, increasing the risk of unintended outbound requests or misuse of connected services.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The skill instructs users to place a long-lived Maton API key in the main Clawdbot config file, but it does not prominently warn that this credential is sensitive or discuss filesystem exposure, backups, or access controls. Storing service credentials in a general config location without strong guidance can lead to accidental disclosure through local compromise, logs, config syncing, or unsafe file permissions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This markdown section instructs integrators to add and save MATON_API_KEY, which is a sensitive credential, but it does not include any warning about secure storage, access controls, or the sensitivity of the key. Under the markdown-specific warning criterion, credential-handling behavior that could affect privacy or system integrity should be disclosed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This function stores a sensitive credential in the config file and triggers a gateway restart, but the code provides no confirmation prompt, visible log/print, or user-facing disclosure about persisting the API key. For code files, sensitive credential handling should include some form of warning or disclosure unless it is clearly surfaced elsewhere in skill documentation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The request helper sends the user's Maton API key as a Bearer token to an external service, but there is no confirmation, visible disclosure, or warning in this code path that credentials are being transmitted off-box. Under the code-file criteria, network calls involving sensitive data should have some form of user disclosure unless clearly covered by the skill's stated purpose or documentation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This handler performs a DELETE request to remove a Maton connection and immediately returns success, but it contains no confirmation prompt or user-facing warning about the destructive action. For code files, destructive or irreversible operations should include some form of disclosure unless the operation is already clearly warned about elsewhere.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The function directly issues a deletion request for a connection and removes it from local state, but this file shows no confirmation prompt, warning text, or comment indicating that the user is explicitly informed before the destructive action. Deleting an existing connection is potentially irreversible and should normally include a clear user warning or confirmation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The UI exposes a destructive 'Delete' action for OAuth/app connections with no user-facing confirmation, undo path, or contextual warning. In an integration-management skill, accidental clicks or UI automation mistakes can immediately remove live SaaS connections, causing loss of service and potentially interrupting workflows until the user reauthorizes access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This code launches an external OAuth URL with window.open, which is a network/navigation action that can affect user context and send them to a third-party authorization flow. Although a success message is shown after opening the window, there is no visible warning or confirmation before the action occurs in this file.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
reference/README.md:120