Back to skill

Security audit

Olvid Channel

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Olvid channel plugin, but it handles credentials, message attachments, and shutdown control in ways that should be reviewed before installation.

Review this before installing. Use only a local daemon or an HTTPS daemon you control, treat the Olvid client key as a secret that may be stored in OpenClaw configuration, and avoid enabling this in environments where untrusted senders can push large attachments until attachment limits and cleanup are addressed. Be aware that stopping the account may not fully stop message processing until the plugin process exits.

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
src/setup.ts:20
Finding

Client Key Can Be Transmitted to an Arbitrary Plaintext HTTP Endpoint

Content
View full analysis
{ if (input.useEnv && accountId !== DEFAULT_ACCOUNT_ID) { return "Olvid env vars can only be used for the default account."; } const clientKey = input.botToken ?? input.token; const daemonUrl = input.url ?? input.httpUrl; if (!input.useEnv && (!clientKey || !daemonUrl)) { return "Olvid requires --bot-token and --http-url (or --use-env)."; } if (!daemonUrl?.startsWith("https://") && !daemonUrl?.startsWith("http://")) { return "Olvid --url must include a valid base URL."; } return null; }, ``` ```ts // src/monitor.ts:25-27 constructor(account: ResolvedOlvidAccount, opts: MonitorOlvidOpts, cfg: CoreConfig) { super({ serverUrl: account.daemonUrl, clientKey: account.clientKey }); this.opts = opts; ``` ```ts // src/tools.ts:45-54 export function getOlvidClient(olvidChannelAccountId?: string): OlvidClient { const runtime = getOlvidRuntime(); const config = runtime.config.loadConfig(); // Retrieve the configuration/credentials for the specific olvidChannelAccountId, or fallback to default let olvidAccount: ResolvedOlvidAccount = resolveOlvidAccount({cfg: config as CoreConfig, accountId: olvidChannelAccountId ?? "default"}); if (!olvidAccount || !olvidAccount.daemonUrl || !olvidAccount.clientKey) { olvidAccount = resolveOlvidAccount({cfg: config as CoreConfig, accountId: "default"}); } return new OlvidClient({clientKey: olvidAccount.clientKey, serverUrl: olvidAccount.daemonUrl}); } ``` ```json // openclaw.plugin.json:21-26 "properties": { "daemonUrl": { "type": "string", "default": "http://localhost:50051" }, "clientKey": { "type" ...[truncated 2569 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/monitor.ts:81
Finding

Inbound Attachments Are Saved in a Shared Persistent Temporary Directory Without Limits or Cleanup

Content
View full analysis
0) { fs.mkdirSync("/tmp/olvid-attachments", {recursive: true}); for await (const attachment of this.attachmentList({filter: new datatypes.AttachmentFilter({messageId: message.id})})) { attachmentsWithPaths.push({ attachment: attachment, path: await attachment.save(this, "/tmp/olvid-attachments") }) } this.logger?.info(`downloaded ${attachmentsWithPaths.length} attachment(s)`) } ``` ### Technical Analysis Every inbound attachment is written beneath the fixed, predictable directory `/tmp/olvid-attachments`. The code does not: - Create a private directory for the current process or message. - Set restrictive permissions. - Enforce a maximum attachment count or aggregate byte limit. - Validate or generate destination filenames itself. - Remove downloaded attachments after agent processing. - Use a `finally` block to guarantee cleanup after failures. Attachments originate from remote Olvid participants and must therefore be treated as untrusted input. Persisting them in a shared predictable location can retain sensitive user data after processing. Repeated messages with large or numerous attachments can consume disk space. Depending on how the dependency chooses filenames, shared-directory reuse may also create collision or local interference risks. The directory is used to support the declared media functionality, but a global persistent directory and unbounded retention are not necessary for that function. ### Attack Path 1. An attacker who can send messages to an accepted Olvid discussion sends messages containing numerous or large attachments. ...[truncated 1351 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/monitor.ts:209
Finding

Stopping an Account Does Not Terminate Its Monitor or Reconnection Loop

Content
View full analysis
) => ctx.setStatus({ accountId: ctx.accountId, ...patch }), }); }, stopAccount: async (ctx) => { ctx.setStatus({ accountId: ctx.accountId, lastStopAt: Date.now() }); }, ``` ```ts // src/monitor.ts:209-247 let globalRunBot = false; export async function monitorOlvidProvider(opts: MonitorOlvidOpts = {}): Promise { const core = getOlvidRuntime(); const cfg: CoreConfig = opts.config ?? (core.config.loadConfig() as CoreConfig); const account = resolveOlvidAccount({ cfg: cfg, accountId: opts.accountId }); if (!account.daemonUrl) { throw new Error(`Olvid daemon url not configured for account "${account.accountId}"`); } if (!account.clientKey) { throw new Error(`Olvid client key not configured for account "${account.accountId}"`); } globalRunBot = true; while (globalRunBot) { try { let bot = new OpenClawBot(account, opts, cfg); opts.statusSink?.({connected: true, lastConnectedAt: Date.now()}); await bot.waitForCallbacksEnd(); } catch (err) { opts.logger?.error(`olvid: ${err}`); opts.statusSink?.({ lastError: String(err), connected: false, lastDisconnect: {at: Date.now(), error: String(err)}, }); } opts.logger?.info("wait before reconnection try") await new Promise(resolve => setTimeout(resolve, 5_000)); } } ``` ### Technical Analysis The gateway passes an `AbortSignal` to `monitorOlvidProvider`, but the monitor never checks it or registers an abort handler. The `sto ...[truncated 1822 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
package.json:14
Finding

Publishing Script Executes an Unpinned Package Through npx

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (16)

Known Vulnerable Dependency: @hono/node-server==1.19.9 — 3 advisory(ies): CVE-2026-39406 (@hono/node-server: Middleware bypass via repeated slashes in serveStatic); GHSA-frvp-7c67-39w9 (Node.js Adapter for Hono: Path traversal in `serve-static` on Windows via encode); CVE-2026-29087 (@hono/node-server has authorization bypass for protected static paths via encode)

High
Category
Supply Chain
Confidence
80% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: undici==7.21.0 — 16 advisory(ies): CVE-2026-1525 (Undici has an HTTP Request/Response Smuggling issue); CVE-2026-6733 (undici vulnerable to HTTP response queue poisoning via keep-alive socket reuse); CVE-2026-1527 (Undici has CRLF Injection in undici via `upgrade` option) +13 more

High
Category
Supply Chain
Confidence
97% confidence
Finding

undici 7.21.0 appears in the lockfile as a concrete installed transitive dependency, including under the OpenClaw stack, and the listed advisories include request smuggling, response queue poisoning, and CRLF injection classes. Because this skill operates in a networked agent ecosystem and depends on OpenClaw and AI/network SDKs, vulnerable HTTP client behavior can affect outbound service-to-service communication and may be exploitable in realistic deployments.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: @mariozechner/pi-coding-agent==0.52.7 — 3 advisory(ies): CVE-2026-54326 (Pi Agent: Potential XSS in HTML session exports via Markdown URL sanitization by); CVE-2026-54328 (Pi Agent: Predictable temporary extension install paths allow local privilege es); CVE-2026-54327 (Pi Agent: Race condition in Pi auth.json writes could expose stored credentials)

High
Category
Supply Chain
Confidence
80% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

The second RP1 finding is the same underlying issue: npx clawhub is executed without a pinned version in a release script. Because npx can resolve and run remote package code, a compromised or changed upstream package could execute arbitrary code in the publisher's environment and affect credentials or published artifacts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Inbound message attachments are automatically persisted to a fixed directory under /tmp before any policy check, size/type validation, or explicit user approval. In a messaging integration, this increases exposure to malicious or sensitive files, can leave recoverable data on disk, and may enable disk-filling or downstream processing risks if other components trust these saved paths.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill reads a sensitive client key from an environment variable and then proceeds to use it during onboarding, which expands secret ingestion beyond explicit user entry. Although the code asks for confirmation, pulling long-lived credentials from process environment increases the chance of unintended secret exposure or persistence, especially in shared shells, CI environments, or inherited process contexts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The client key is written into the configuration object without any user-facing warning that a sensitive credential will be persisted. If the configuration is stored in plaintext or in a broadly accessible location, this can expose the credential to other local users, backups, logs, or accidental source control commits.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: @protobufjs/utf8==1.1.0 — 1 advisory(ies): CVE-2026-44288 (protobufjs has overlong UTF-8 decoding)

Low
Category
Supply Chain
Confidence
60% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 7)May include surrounding context.

json
"description": "Olvid native channel for OpenClaw.",
  "type": "module",
  "dependencies": {
    "@olvid/bot-node": "^1.5.0",
    "zod": "^4.3.6"
  },
  "devDependencies": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 8)May include surrounding context.

json
"type": "module",
  "dependencies": {
    "@olvid/bot-node": "^1.5.0",
    "zod": "^4.3.6"
  },
  "devDependencies": {
    "typescript": "^5.9.3"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 11)May include surrounding context.

json
"zod": "^4.3.6"
  },
  "devDependencies": {
    "typescript": "^5.9.3"
  },
  "peerDependencies": {
    "openclaw": "2026.2.6-3"

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The code reads process.env.OLVID_CLIENT_KEY and process.env.OLVID_DAEMON_TARGET, which are sensitive configuration values, but there is no confirmation prompt, logging, comment, or docstring disclosing that the skill will consume environment-provided credentials/settings. For code files, accessing sensitive environment variables without any visible disclosure matches the missing user warnings criterion.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

Reading process environment variables such as OLVID_DAEMON_TARGET and OLVID_CLIENT_KEY introduces access to host-provided configuration and secrets. For a skill described only as adding a native Olvid channel, that capability is not explicitly justified by the stated purpose, even though it may be convenient for onboarding.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The manifest description says only 'Add a native Olvid channel in OpenClaw,' which suggests channel integration at a high level. In this file, the adapter not only enables the channel but also collects a sensitive client key from environment variables or user prompts and stores it into configuration, expanding the behavior into credential onboarding and persistence.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This code sends user-provided text and optional attachment paths to an external Olvid client via messageSendWithAttachmentsFiles and messageSend, which is a network/data-transmission operation. While the function name suggests sending is its purpose, the file itself provides no user-facing confirmation, prompt, or explicit disclosure beyond a brief developer comment, so there is no visible warning at the point of transmission in this code file.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.