Back to skill

Security audit

Verify Matrix device

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to do Matrix device verification, but it can send Matrix access tokens or passwords to any homeserver URL supplied at runtime.

Review before installing. Use only a homeserver URL you recognize and trust, prefer HTTPS, avoid homeserver values supplied by untrusted prompts, and avoid --password unless necessary. Protect openclaw.json and consider updating or pinning dependencies before use.

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

Error
Location
scripts/verify_matrix_device_sdk.mjs:200
Finding
Unrestricted homeserver destination can expose Matrix access tokens or passwords<![CDATA[ ## Vulnerability Details **File Location**: `scripts/verify_matrix_device.mjs:207-228`, `scripts/verify_matrix_device_sdk.mjs:200-248` **Vulnerability Type**: Credentials transmitted to an unvalidated, user-controlled network destination **Risk Level**: High ### Vulnerable Code From `scripts/verify_matrix_device.mjs:207-228`: ```js const homeserver = await promptRequiredText("Homeserver URL", args.homeserver); let account; if (args["access-token"]) { const userId = await promptRequiredText("Matrix user ID", args["user-id"] || args.username); const targetAccessToken = await promptRequiredSecret("Access token (hidden)"); account = { accountId: null, userId, targetAccessToken }; console.log(`[+] Access-token mode target: ${account.userId}`); } else if (args.password) { const userId = await promptRequiredText("Matrix user ID", args["user-id"] || args.username); const password = await promptRequiredSecret("Password (hidden)"); const targetDeviceId = await promptRequiredText("Target device ID", args["device-id"]); account = { accountId: null, userId, password, targetDeviceId }; console.log(`[+] Password mode target: ${account.userId} / ${account.targetDeviceId}`); } else { const openclawJsonPath = args["openclaw-json"] || DEFAULT_OPENCLAW_JSON; if (!fs.existsSync(openclawJsonPath)) { throw new Error(`OpenClaw config not found at ${openclawJsonPath}. Use --access-token or --password to test without openclaw.json.`); } const oc = readJson(openclawJsonPath); const username = await promptRequiredText("Username", args.username); account = resolveOpenClawAccount(oc, username, openclawJsonPath); ``` From `scripts/verify_matrix_device_sdk.mjs:200-248`: ```js async function matrixRequest({ homeserver, accessToken, path, method = "GET", body }) { const headers = {}; if (accessToken) { headers.Authorization = `Bearer ${accessToken}`; } if (body !== undefined) { headers["Content-Type"] = "application/json"; } ...[truncated 3916 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse the homeserver with `new URL()` before handling any credential. 2. Require the `https:` protocol in normal operation. Permit HTTP only through an explicit development-only option with a prominent warning. 3. Reject URLs containing embedded usernames or passwords, fragments, or otherwise unexpected URL components. 4. Obtain the expected homeserver from trusted per-account configuration or trusted Matrix discovery and bind the selected account to that origin. 5. If a caller supplies an override that differs from the configured origin, require explicit confirmation that clearly identifies the destination and warns that credentials will be sent there. 6. Reject loopback, link-local, private, and other non-public destinations by default, with a narrowly scoped opt-in for legitimate local testing. 7. Configure requests with `redirect: "manual"` and reject redirects for authenticated requests, or explicitly verify that any redirect remains on the previously approved origin. 8. Separate credential-bearing requests from unauthenticated discovery. Do not attach an access token until the destination has been validated. 9. Prefer an existing access token over password authentication, and clearly document that password mode submits the password to the selected homeserver. 10. Add automated tests covering HTTP URLs, attacker-controlled domains, embedded credentials, private IP addresses, mismatched account origins, and cross-origin redirects. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (21)

Credential Access

High
Category
Privilege Escalation
Content
- No secrets are embedded in the repository
- No default homeserver is hardcoded
- Access tokens, passwords, and recovery keys are hidden while typed
- `verify-account` and `verify-direct` run through `scripts/verify_matrix_device.mjs` and do not create a helper login or temporary Matrix device
- `verify-direct` now runs access-token mode
- `verify-password` runs through `scripts/verify_matrix_device.mjs`, creates a temporary helper session only to fetch account data and upload the signature, then logs it out
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
## Notes

- The skill uses the existing OpenClaw access token from `openclaw.json`; it does not create a helper Matrix device.
- The verifier signs the active device directly and confirms the signature server-side.
- Use a real TTY so the hidden recovery-key prompt works correctly.
- For local testing outside OpenClaw, `--access-token` bypasses `openclaw.json` and prompts for the Matrix user ID plus access token (`--direct` and `-t` are compatibility aliases).
Confidence
90% confidence
Finding
This skill explicitly uses an existing OpenClaw access token from openclaw.json to authenticate and perform signing actions. Even though the text does not direct exfiltration, handling a pre-existing bearer token is sensitive because compromise of the script, surrounding skill, or runtime could expose a credential that grants Matrix account access.

Credential Access

High
Category
Privilege Escalation
Content
- The skill uses the existing OpenClaw access token from `openclaw.json`; it does not create a helper Matrix device.
- The verifier signs the active device directly and confirms the signature server-side.
- Use a real TTY so the hidden recovery-key prompt works correctly.
- For local testing outside OpenClaw, `--access-token` bypasses `openclaw.json` and prompts for the Matrix user ID plus access token (`--direct` and `-t` are compatibility aliases).
- If the access token is missing, `--password` (or `-p`) can log in with the Matrix password and sign a specific target `device_id`, then log out the temporary helper session.
Confidence
87% confidence
Finding
The documented --access-token mode allows a user to supply a Matrix access token directly for local testing, which is a high-value secret. Direct token entry expands the number of pathways through which credentials may be mishandled, captured in terminal history/process inspection, or reused outside the intended verification task if surrounding controls are weak.

Credential Access

High
Category
Privilege Escalation
Content
- The verifier signs the active device directly and confirms the signature server-side.
- Use a real TTY so the hidden recovery-key prompt works correctly.
- For local testing outside OpenClaw, `--access-token` bypasses `openclaw.json` and prompts for the Matrix user ID plus access token (`--direct` and `-t` are compatibility aliases).
- If the access token is missing, `--password` (or `-p`) can log in with the Matrix password and sign a specific target `device_id`, then log out the temporary helper session.
Confidence
91% confidence
Finding
The fallback --password flow introduces another highly sensitive credential and enables the tool to log in and create a helper session before logging out. Password-based authentication materially increases risk because passwords are reusable credentials; if intercepted or mishandled, the impact is broader than a single device-verification action and may persist beyond token revocation.

Credential Access

High
Category
Privilege Escalation
Content
if (args["access-token"]) {
    const userId = await promptRequiredText("Matrix user ID", args["user-id"] || args.username);
    const targetAccessToken = await promptRequiredSecret("Access token (hidden)");
    account = { accountId: null, userId, targetAccessToken };
    console.log(`[+] Access-token mode target: ${account.userId}`);
  } else if (args.password) {
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env node
/*
Direct verifier for the active OpenClaw Matrix device.
- Resolves the active device_id via /whoami using the existing access token.
- Restores the self-signing private key from SSSS using the recovery key.
- Signs the active device directly via /keys/signatures/upload.
- Does not print secrets or create a helper device.
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env node
/*
Direct verifier for the active OpenClaw Matrix device.
- Resolves the active device_id via /whoami using the existing access token.
- Restores the self-signing private key from SSSS using the recovery key.
- Signs the active device directly via /keys/signatures/upload.
- Does not print secrets or create a helper device.
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env node
/*
Direct verifier for the active OpenClaw Matrix device.
- Resolves the active device_id via /whoami using the existing access token.
- Restores the self-signing private key from SSSS using the recovery key.
- Signs the active device directly via /keys/signatures/upload.
- Does not print secrets or create a helper device.
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env node
/*
Direct verifier for the active OpenClaw Matrix device.
- Resolves the active device_id via /whoami using the existing access token.
- Restores the self-signing private key from SSSS using the recovery key.
- Signs the active device directly via /keys/signatures/upload.
- Does not print secrets or create a helper device.
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env node
/*
Direct verifier for the active OpenClaw Matrix device.
- Resolves the active device_id via /whoami using the existing access token.
- Restores the self-signing private key from SSSS using the recovery key.
- Signs the active device directly via /keys/signatures/upload.
- Does not print secrets or create a helper device.
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env node
/*
Direct verifier for the active OpenClaw Matrix device.
- Resolves the active device_id via /whoami using the existing access token.
- Restores the self-signing private key from SSSS using the recovery key.
- Signs the active device directly via /keys/signatures/upload.
- Does not print secrets or create a helper device.
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
const helperLogin = await loginWithPassword(homeserver, userId, password);
  const helperAccessToken = helperLogin?.access_token;
  if (!helperAccessToken) {
    throw new Error("Password login did not return an access token.");
  }

  const resolvedTargetDeviceId = targetDeviceId || helperLogin.device_id;
Confidence
84% confidence
Finding
This code derives a fresh access token from a user password via password login, materially increasing the credential exposure and privilege-handling surface of the skill. If the surrounding agent, logs, prompts, or calling environment mishandle the password or returned token, an attacker could obtain authenticated account access rather than only performing a narrow verification action.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill instructs the agent to install packages and run a network-capable Node script, but it does not declare any explicit tool restrictions such as allowed tools or permissions. That creates an avoidable trust gap: an agent may execute shell, network, and environment-accessing actions without a clearly bounded scope, which increases the chance of overbroad execution or abuse if the skill or its dependencies are modified.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
In default mode, the script silently loads the OpenClaw config file and consumes Matrix account access tokens from it. While the script prompts for inputs elsewhere, there is no explicit warning at the point of execution that local stored credentials will be accessed, which is a safety-relevant operation for a verification tool handling secrets.

Intent-Code Divergence

Medium
Confidence
92% confidence
Finding
The header comment claims the script 'does not ... create a helper device,' but the code includes a password-login path that may create a temporary authenticated session/device. Security-relevant documentation drift is dangerous because reviewers and downstream automation may trust the comment and miss that the code can handle passwords and create additional authenticated state.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The file implements a password-based helper login/logout flow that expands the skill’s effective security boundary beyond the stated 'active-device verification' behavior. This introduces credential handling and temporary session creation, which increases attack surface and can violate operator expectations or policy if callers assume only an existing token will be used.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The password login path accepts primary account credentials and creates an authenticated helper session without any explicit user-facing warning in this flow. In a credential-sensitive Matrix recovery/cross-signing context, silent credential collection and session creation increase the chance of unsafe use, mishandling of passwords, and unexpected account changes.

Known Vulnerable Dependency: matrix-js-sdk==34.13.0 — 1 advisory(ies): CVE-2025-59160 (matrix-js-sdk has insufficient validation when considering a room to be upgraded)

Low
Category
Supply Chain
Confidence
89% confidence
Finding
The lockfile pins matrix-js-sdk to 34.13.0, and the supplied advisory indicates this version has insufficient validation around determining whether a room has been upgraded. That is a real supply-chain risk, though the impact is limited here because this skill’s stated purpose is device verification and cross-signing rather than room-upgrade management; exploitation would likely require crafted Matrix room state and would more plausibly affect trust or workflow correctness than directly compromise the host.

Known Vulnerable Dependency: uuid==11.1.0 — 1 advisory(ies): CVE-2026-41907 (uuid: Missing buffer bounds check in v3/v5/v6 when buf is provided)

Low
Category
Supply Chain
Confidence
81% confidence
Finding
The lockfile includes uuid 11.1.0 transitively, and the referenced advisory describes missing buffer bounds checks in certain UUID generation paths when a caller provides a buffer. This is a genuine vulnerable dependency finding, but risk is reduced in this skill because the issue is only reachable if the application or one of its libraries uses the affected v3/v5/v6 APIs with attacker-influenced buffer arguments; from the lockfile alone there is no evidence of active exploitation.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"verify-password": "node scripts/verify_matrix_device.mjs --password"
  },
  "dependencies": {
    "matrix-js-sdk": "^34.3.0"
  }
}
Confidence
97% confidence
Finding
The dependency is specified with a caret range (^34.3.0), which allows newer minor and patch versions to be installed without explicit review. In a security-sensitive skill that performs Matrix device verification and cross-signing, this weakens supply-chain control and can unexpectedly pull in a vulnerable or behavior-changing release.

Known Vulnerable Dependency: matrix-js-sdk==34.13.0 — 1 advisory(ies): CVE-2025-59160 (matrix-js-sdk has insufficient validation when considering a room to be upgraded)

Low
Category
Supply Chain
Confidence
80% confidence
Finding
The flagged version range can resolve to matrix-js-sdk 34.13.0, which has an advisory for insufficient validation when treating a room as upgraded. Although this skill's stated purpose is device verification rather than room-upgrade handling, the vulnerable library may still be present in the execution environment and should not be relied on if a fixed release exists.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/verify_matrix_device_sdk.mjs:430

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/verify_matrix_device.mjs:252