Back to skill

Security audit

Opik Reporter

Security checks for vulnerabilities and agentic risk

Overview

This skill is an observability reporter, but it ships a hardcoded API key and Discord destination while recommending recurring automatic sends, so users should review it before installing.

Do not install this version for real monitoring without changes. Rotate the exposed Opik key if it is real, replace it with a user-supplied secret, require a user-selected Discord target, add a dry-run/local-only mode, and clearly label the current output as mock data unless live Opik collection is implemented.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
config/settings.json:2
Finding

Hardcoded Opik API Credential Exposed in Configuration and Documentation

Content
View full analysis

Vulnerability Details

File Location: config/settings.json:2-7; duplicated in SKILL.md:134-148
Vulnerability Type: Hardcoded plaintext credential
Risk Level: High

Vulnerable Code

config/settings.json:2-7:

json
"opik": {
  "apiKey": "I5xMCUAO14m4EyckFWfqQla3O",
  "workspace": "default",
  "project": "openclaw",
  "apiUrl": "https://www.comet.com/opik/api"
}

SKILL.md:134-148:

json
{
  "opik": {
    "apiKey": "I5xMCUAO14m4EyckFWfqQla3O",
    "workspace": "default",
    "project": "openclaw"
  },
  "discord": {
    "channel": "discord",
    "to": "channel:1481801666851373138"
  },
  "reportSchedule": {
    "hourly": true,
    "daily": true,
    "onError": true
  }
}

Technical Analysis

An Opik API key is embedded directly in the distributed configuration and repeated in the user documentation. Any person or system able to read the package can recover the credential without needing access to a protected secret store.

The current reporter implementation does not load or transmit this key, so the audit did not identify credential exfiltration by scripts/reporter.cjs. Nevertheless, distributing a reusable credential in plaintext independently exposes it. Its actual capabilities depend on the server-side permissions assigned to the key.

Attack Path

  1. An attacker obtains the Skill package, repository contents, build artifact, or documentation.
  2. The attacker reads the plaintext key from config/settings.json or SKILL.md.
  3. The attacker submits the key to the configured Opik service or another valid Opik API endpoint.
  4. If the key remains active, the attacker performs operations permitted by its assigned workspace and API scopes.

No claim is made that the credential is currently active; revocation status cannot be established through static analysis.

Impact Assessment

If valid, the exposed key may permit unauthorized ...[truncated 378 chars]

Remediation
View remediation

Remediation Suggestions

  1. Revoke and rotate the exposed API key immediately.
  2. Remove the credential from config/settings.json, SKILL.md, repository history, release archives, logs, and cached artifacts.
  3. Require users to supply their own credential through a protected environment variable or secret manager, for example OPIK_API_KEY.
  4. Ensure example configuration uses an unmistakable placeholder such as ${OPIK_API_KEY} rather than a realistic credential.
  5. Restrict the replacement key to the minimum workspace and read-only scopes required for reporting.
  6. Add automated secret scanning to development and release pipelines.
  7. Review service audit logs for use of the exposed credential and investigate unexpected requests.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/reporter.cjs:16
Finding

Reports Are Sent to a Hardcoded External Discord Channel

Content
View full analysis

Vulnerability Details

File Location: scripts/reporter.cjs:16-21 and scripts/reporter.cjs:133-145; destination also appears in config/settings.json:8-12
Vulnerability Type: Hardcoded external data destination
Risk Level: Medium

Vulnerable Code

scripts/reporter.cjs:16-21:

js
// 配置
const CONFIG = {
  statusFile: '/Users/xufan65/.openclaw/workspace/memory/opik-reporter-status.json',
  notifyChannel: 'discord',
  notifyTo: 'channel:1481801666851373138'
};

scripts/reporter.cjs:133-145:

js
/**
 * 发送到 Discord
 */
sendToDiscord(report) {
  try {
    const message = report.substring(0, 1900); // Discord 限制
    const escapedMessage = message.replace(/"/g, '\\"').replace(/\n/g, '\\n');
    execSync(`openclaw message send --channel discord --target "${CONFIG.notifyTo}" --message "${escapedMessage}"`, { 
      encoding: 'utf8' 
    });
    console.log('\n✅ 报告已推送到 Discord');
  } catch (e) {
    console.error('\n❌ 推送到 Discord 失败:', e.message);
  }
}

config/settings.json:8-12:

json
"discord": {
  "channel": "discord",
  "to": "channel:1481801666851373138"
},

Technical Analysis

The reporter always invokes the local openclaw CLI to send report content to a fixed Discord channel. It does not load config/settings.json at runtime or require the user to confirm ownership of the destination. Consequently, every installation uses the package author's embedded channel identifier.

Sending reports to Discord is consistent with the declared reporting function, but selecting a third-party destination without installation-specific configuration exceeds minimum privilege and violates destination control expectations.

The present generateReport() implementation contains simulated, hardcoded statistics rather than collected Opik traces. Therefore, the reviewed version does not currently exfiltrate actual trace content, credentials, or arbitr ...[truncated 1361 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the embedded Discord channel identifier from source code and distributed configuration.
  2. Require the destination to be explicitly supplied during installation or execution.
  3. Load configuration from a documented user-controlled location and fail closed when no destination is configured.
  4. Display the resolved channel and require confirmation before the first transmission.
  5. Validate that the configured destination is authorized for the current user or deployment.
  6. Apply data minimization before transmission: omit prompts, credentials, raw errors, trace payloads, and personal data unless explicitly enabled.
  7. Provide a dry-run mode that prints the destination and report without sending it.
  8. Record outbound delivery metadata locally so users can audit when and where reports were sent.
  9. Before incorporating externally sourced trace content, replace shell-based execSync() interpolation with an argument-based API such as execFileSync('openclaw', args) to prevent shell interpretation.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module header explicitly states that the script fetches trace data, analyzes usage and cost, and generates reports, but the code uses only simulated data. This mismatch is a security-relevant integrity issue because it can mislead users into believing they have operational visibility when they do not.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill advertises that it fetches and analyzes Opik trace data, but the implementation only emits hard-coded mock values. This is dangerous because operators may trust and act on fabricated observability, cost, and error data, leading to missed incidents, incorrect reporting, and false assurance that monitoring is functioning.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description states that it fetches trace data, analyzes usage and errors, and sends reports to Discord, but it does not clearly warn that operational and potentially sensitive trace-derived data will be transmitted to an external service. This creates a transparency and data-handling risk because users may enable the skill without understanding that internal metadata, errors, or other sensitive content could leave their environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The scheduled hourly reporting instructions set up ongoing background collection and automatic delivery to Discord without warning about continuous external transmission. In context, this is more dangerous because automation increases the chance of repeated leakage of internal observability data, including error details and trace-derived information, without active user review each time.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The documentation exposes a hardcoded Opik API key in a configuration example, which is a direct secret disclosure even if presented as sample content. API keys can enable unauthorized access to telemetry, usage, trace, and project data, and because this skill is specifically designed to fetch observability data, the leaked credential is especially relevant and likely usable.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The report timestamp is forced to use the 'zh-CN' locale and 'Asia/Shanghai' timezone. This is a natural-language locale policy issue because the script imposes a specific language/region format without any user opt-in or documented justification that the tool is region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The invocation message explicitly states '报告格式用中文', which imposes a language preference in the skill usage instructions. The policy requires avoiding forced language or locale constraints unless the user is given a choice or the restriction is clearly justified.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/reporter.cjs:97