T09 · Insecure Skill Coding Practices
- Location
scripts/verify_matrix_device_sdk.mjs:200- Finding
Unrestricted homeserver destination can expose Matrix access tokens or passwords
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
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.
scripts/verify_matrix_device_sdk.mjs:200Unrestricted homeserver destination can expose Matrix access tokens or passwords
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- 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
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.
## 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).
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.
- 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.
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.
- 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.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
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) {
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
#!/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.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
#!/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.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
#!/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.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
#!/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.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
#!/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.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
#!/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.
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.
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;
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.
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.
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.
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.
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.
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.
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.
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.
"verify-password": "node scripts/verify_matrix_device.mjs --password"
},
"dependencies": {
"matrix-js-sdk": "^34.3.0"
}
}
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.
Detected: suspicious.exposed_secret_literal