Back to skill

Security audit

Nirvana

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent local AI routing plugin, but its privacy promises, cloud-routing controls, permissions, and Docker install guidance are too broad and inconsistent for automatic installation.

Review this before installing on any sensitive OpenClaw environment. Use local-only settings, verify that cloud routing is actually disabled, do not enter secrets in prompts unless you have confirmed no cloud provider can be invoked, bind Docker services to localhost, replace fixed credentials, pin images/releases, and narrow manifest permissions to plugin-owned files and Ollama API access.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (6)

T09 · Insecure Skill Coding Practices

Error
Location
src/router.js:15
Finding
Cloud fallback opt-out is ignored and raw queries bypass privacy sanitization<![CDATA[ ## Vulnerability Details **File Location**: `src/router.js:15-16, 45-56, 224-307`; `src/index.js:106-109, 173-179` **Vulnerability Type**: Privacy control bypass and unintended external data disclosure **Risk Level**: High ### Vulnerable Code ```javascript // src/router.js this.localFirst = this.config.localFirst !== false; this.localThreshold = this.config.localThreshold || 0.8; this.cloudFallback = this.config.cloudFallback !== false; ``` ```javascript // src/router.js if (!this.localFirst || !ollamaAvailable) { if (!cloudAvailable) { throw new Error('No inference provider available (Ollama down, no cloud API)'); } decision = { provider: 'cloud', model: this.selectCloudModel(), reasoning: 'Local unavailable or disabled' }; this.stats.cloudDecisions++; } else { decision = this.applyRoutingLogic(analysis); } ``` ```javascript // src/index.js if (decision.provider === 'local') { response = await this.executeLocal(query, context, decision.model); } else { // Strip context before sending to cloud const strippedContext = await this.contextStripper.strip(context, query); response = await this.executeCloud(query, strippedContext, decision.model); } ``` ```javascript // src/index.js async executeCloud(query, strippedContext, model) { const result = await this.openclaw.query(query, { model, context: strippedContext, provider: 'cloud' }); return { text: result.response, model, provider: 'cloud', tokens: result.tokens || {} }; } ``` ### Technical Analysis The router reads `cloudFallback`, but no routing branch enforces it. The configured value therefore has no effect on decisions made by `applyRoutingLogic()`. Token-count, complexity, domain-confidence, and hybrid routing can all return a cloud decision even when `cloudFallback` is explicitly set to `false`. The privacy layer only sanitizes the context object. The original `query` is passed unchanged to `openclaw.query()`. Conseque ...[truncated 1362 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Enforce the cloud opt-out immediately before every cloud call: ```javascript if (decision.provider !== 'local' && !this.config.routing?.cloudFallback) { decision = { provider: 'local', model: this.config.ollama?.bundledModel || 'qwen2.5:7b', reasoning: 'Cloud fallback disabled' }; } ``` 2. Add a second fail-closed check inside `executeCloud()` so routing defects cannot bypass policy. 3. Sanitize both the query and context before transmission. 4. Validate the final outbound payload rather than only the original context. 5. Treat `hybrid` as a distinct execution path with explicit local and optional cloud phases. 6. Require explicit user consent before sending a prompt identified as sensitive. 7. Add tests proving that no cloud API is invoked when `cloudFallback` is false. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
plugin-manifest.json:67
Finding
Plugin manifest requests unnecessary access to identity, memory, session, and execution capabilities<![CDATA[ ## Vulnerability Details **File Location**: `plugin-manifest.json:67-84` **Vulnerability Type**: Excessive permissions and violation of least privilege **Risk Level**: High ### Vulnerable Code ```json "permissions": { "read": [ "SOUL.md", "USER.md", "MEMORY.md", "AGENTS.md", "SESSION-STATE.md" ], "write": [ "memory/*", "SESSION-STATE.md" ], "execute": [ "docker", "ollama-api" ] } ``` ### Technical Analysis The implementation accepts query context through function parameters and does not directly read the listed identity files. It also does not write `SESSION-STATE.md` or execute Docker commands. The declared permissions therefore exceed the demonstrated requirements of the plugin. Identity and memory files are especially sensitive because they can contain user profiles, long-term agent state, operational instructions, and private conversation material. Docker execution can represent a high-impact host capability depending on how OpenClaw interprets and enforces manifest permissions. Although the current source does not abuse these permissions, granting them expands the damage possible from a compromised dependency, future malicious update, or unrelated code-execution vulnerability in the plugin. ### Attack Path 1. A user installs the plugin and approves the declared manifest permissions. 2. OpenClaw grants access to identity files, memory state, session state, and execution facilities. 3. A compromised update or exploited plugin process uses those permissions. 4. Sensitive agent state can be read or modified. 5. If Docker execution is honored, an attacker may interact with containers or escalate further depending on Docker socket and runtime configuration. ### Impact Assessment Potentially exposed information includes agent identity, user profile data, long-term memory, operational instructions, and session state. Write access can corrupt agent state or influence later sessions. Docker-level exe ...[truncated 92 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove read access to `SOUL.md`, `USER.md`, `MEMORY.md`, `AGENTS.md`, and `SESSION-STATE.md` unless direct access is demonstrably required. 2. Remove write access to `SESSION-STATE.md`. 3. Limit writes to dedicated plugin-owned files such as: - `memory/nirvana-audit.log` - `memory/nirvana-metrics.json` 4. Remove the `docker` execution permission because the implementation uses the Ollama HTTP API. 5. Declare only narrowly scoped network access to a validated local Ollama endpoint. 6. Add permission-focused tests to prevent future releases from silently expanding capabilities. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
INSTALL.md:68
Finding
Installation instructions expose services on all interfaces and deploy a hardcoded database credential<![CDATA[ ## Vulnerability Details **File Location**: `INSTALL.md:18-23, 68-105` **Vulnerability Type**: Insecure service exposure and hardcoded credential **Risk Level**: High ### Vulnerable Code ```bash docker run -d \ --name ollama \ --restart unless-stopped \ -v ollama:/root/.ollama \ -p 11434:11434 \ ollama/ollama ``` ```yaml services: ollama: image: ollama/ollama:latest ports: - "11434:11434" qdrant: image: qdrant/qdrant:latest ports: - "6335:6335" environment: - QDRANT_API_KEY=qdrant_key_v1 falkordb: image: falkordb/falkordb:latest ports: - "6380:6379" openclaw: image: openclaw:latest ports: - "3000:3000" - "8080:8080" ``` ### Technical Analysis Docker port mappings without an explicit host address normally bind to all host interfaces. The documented configuration therefore exposes Ollama, Qdrant, FalkorDB, and OpenClaw ports to any network that can reach the host unless an external firewall blocks them. Ollama and FalkorDB are shown without authentication. Qdrant is configured with the fixed credential `qdrant_key_v1`, which is publicly documented and identical for every user who follows the guide. The configuration also publishes database ports even though services on the same Docker network can communicate without host publication. The `--restart unless-stopped` setting makes the exposed Ollama service persistent across restarts. Persistence is operationally reasonable for a local inference service, but it increases the duration of exposure when combined with unsafe network binding. ### Attack Path 1. A user follows the documented Docker or Docker Compose installation. 2. Docker binds the published ports to externally reachable host interfaces. 3. An attacker scans the local network or exposed host for ports 11434, 6335, 6380, 3000, or 8080. 4. The attacker accesses an unauthenticated service or authenticates to Qdrant using the public fixed key. 5. Th ...[truncated 435 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Bind services intended for local access to loopback: ```yaml ports: - "127.0.0.1:11434:11434" ``` 2. Do not publish Qdrant or FalkorDB ports when only Docker-network clients need them. 3. Generate a unique high-entropy Qdrant key per installation and load it from a protected secret file or secret manager. 4. Add authentication or a mutually authenticated reverse proxy in front of Ollama if remote access is required. 5. Document firewall requirements and warn users not to expose these services directly to the Internet. 6. Use separate internal and external Docker networks and apply least-access network rules. 7. Bind OpenClaw gateway ports to loopback unless remote access is explicitly configured with authentication and TLS. ]]>

T08 · Insecure Dependencies

Warning
Location
INSTALL.md:68
Finding
Installation workflow executes mutable unpinned images and plugin releases<![CDATA[ ## Vulnerability Details **File Location**: `INSTALL.md:68, 84, 95, 102, 266` **Vulnerability Type**: Unpinned supply-chain dependencies **Risk Level**: Medium ### Vulnerable Code ```yaml image: ollama/ollama:latest ``` ```yaml image: qdrant/qdrant:latest ``` ```yaml image: falkordb/falkordb:latest ``` ```yaml image: openclaw:latest ``` ```bash openclaw plugins install ShivaClaw/nirvana@latest ``` ### Technical Analysis The `latest` tag is mutable and does not identify a fixed artifact. The same installation instructions can therefore execute different code over time without any change to the audited project. The plugin upgrade command has the same problem because it retrieves whichever release is currently marked as latest. No digest, signature, checksum, or tested version is specified. If an upstream registry account or repository is compromised, users following these commands can receive malicious code that was not part of this audit. ### Attack Path 1. An upstream image tag or plugin release is replaced, compromised, or unintentionally updated. 2. A user follows the installation or upgrade instructions. 3. Docker or OpenClaw resolves `latest` to the altered artifact. 4. The retrieved code executes as a persistent service or OpenClaw plugin. 5. The code gains access according to container mounts, network access, and plugin permissions. ### Impact Assessment A compromised dependency could access mounted OpenClaw data, intercept prompts, alter agent behavior, expose services, or compromise containers. Impact may extend to the host if Docker or mounted resources are configured unsafely. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every container to a tested semantic version and immutable digest: ```yaml image: ollama/ollama:0.x.y@sha256:EXPECTED_DIGEST ``` 2. Pin the plugin to a reviewed version rather than `@latest`. 3. Verify image signatures or provenance attestations where available. 4. Maintain a documented compatibility matrix of reviewed versions. 5. Use automated dependency monitoring, but require review and testing before changing pins. 6. Provide a controlled rollback procedure for dependency upgrades. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
src/privacy-auditor.js:15
Finding
Configuration-controlled log paths allow arbitrary writable-file modification<![CDATA[ ## Vulnerability Details **File Location**: `src/privacy-auditor.js:15, 24-32, 108-112`; `src/metrics-collector.js:14, 31-41, 151-155` **Vulnerability Type**: Unrestricted filesystem path and unsafe file write **Risk Level**: Medium ### Vulnerable Code ```javascript // src/privacy-auditor.js this.auditLogPath = privacyConfig.auditLogPath || 'memory/nirvana-audit.log'; ``` ```javascript // src/privacy-auditor.js const dir = path.dirname(this.auditLogPath); await fs.mkdir(dir, { recursive: true }); const header = `[Nirvana Privacy Audit Log - Started ${new Date().toISOString()}]\n`; await fs.appendFile(this.auditLogPath, header); ``` ```javascript // src/privacy-auditor.js const logLine = JSON.stringify(entry) + '\n'; await fs.appendFile(this.auditLogPath, logLine); ``` ```javascript // src/metrics-collector.js this.metricsPath = monitoringConfig.metricsPath || 'memory/nirvana-metrics.json'; ``` ```javascript // src/metrics-collector.js await fs.writeFile( this.metricsPath, JSON.stringify(metricsToWrite, null, 2) ); ``` ### Technical Analysis Both file destinations are taken directly from configuration and used without canonicalization, base-directory enforcement, traversal rejection, or symlink protection. Absolute paths and paths containing `../` are accepted. The metrics writer uses `writeFile`, which truncates and overwrites an existing writable file. The auditor uses `appendFile`, which can modify an arbitrary writable target. Directory creation also follows the attacker-selected path. Exploitation requires control over plugin configuration or another path by which an attacker can influence these settings. The effect is constrained by the operating-system privileges of the OpenClaw process. ### Attack Path 1. An attacker gains the ability to set `monitoring.metricsPath` or `privacy.auditLogPath`. 2. The attacker supplies an absolute path, traversal path, or path resolving through a symlink. 3. Plugin initialization creates attac ...[truncated 487 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store all plugin files beneath a fixed plugin-owned data directory. 2. Resolve the configured path and verify that it remains inside that directory: ```javascript const base = path.resolve(pluginDataDirectory); const target = path.resolve(base, configuredRelativePath); if (target !== base && !target.startsWith(base + path.sep)) { throw new Error('Configured path escapes plugin data directory'); } ``` 3. Reject absolute paths and traversal components. 4. Open files with restrictive permissions such as mode `0o600`. 5. Protect against symlink attacks by checking each path component and using no-follow semantics where supported. 6. Use atomic temporary-file creation and rename for metrics persistence. 7. Do not permit untrusted users or prompt content to modify plugin configuration. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
src/router.js:440
Finding
Truncated Base64 routing-cache keys permit cross-query decision collisions<![CDATA[ ## Vulnerability Details **File Location**: `src/router.js:35-38, 75-79, 440-444` **Vulnerability Type**: Predictable cache-key collision and routing-policy manipulation **Risk Level**: Medium ### Vulnerable Code ```javascript // Check cache const cacheKey = this.getCacheKey(query); if (this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } ``` ```javascript // Cache decision if (this.config.cachingEnabled !== false) { this.cache.set(cacheKey, decision); this.pruneCache(); } ``` ```javascript getCacheKey(query) { const text = typeof query === 'string' ? query : query.text || ''; return Buffer.from(text).toString('base64').slice(0, 32); } ``` ### Technical Analysis Base64 is an encoding, not a collision-resistant hash. Truncating the encoded value to 32 characters means the routing key is determined by approximately the first 24 bytes of the prompt. Any two prompts with the same initial bytes receive the same cache key regardless of their remaining content. The cache stores routing decisions rather than responses. A decision produced for one prompt can consequently be reused for a materially different prompt. The cache is also not partitioned by user or session and does not implement the configured cache TTL, increasing cross-query and potentially cross-user influence. ### Attack Path 1. An attacker selects a prompt prefix of approximately 24 bytes. 2. The attacker submits a prompt beginning with that prefix whose remaining text causes a cloud routing decision. 3. The router stores the cloud decision under the truncated-prefix cache key. 4. A later sensitive prompt begins with the same prefix but otherwise has different content. 5. The router returns the cached cloud decision without analyzing the later prompt. 6. The later prompt is sent to the cloud path, potentially contrary to its privacy characteristics. The inverse attack is also possible: an attacker can pre-cache a local decision to prevent an otherwise cloud-eligible ...[truncated 350 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the truncated Base64 value with a complete cryptographic digest: ```javascript const crypto = require('crypto'); getCacheKey(query, userId, routingContext) { const text = typeof query === 'string' ? query : query.text || ''; const material = JSON.stringify({ userId, text, routingContext, routingLogic: this.routingLogic, localThreshold: this.localThreshold }); return crypto.createHash('sha256').update(material).digest('hex'); } ``` 2. Include all routing-relevant context and configuration in the key. 3. Partition caches by user and session. 4. Implement and enforce the configured cache TTL. 5. Clear routing caches after reconfiguration or provider-health changes. 6. Reapply hard privacy constraints after retrieving a cached decision, particularly the cloud-fallback opt-out. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (30)

Privileged Container / Container Escape

High
Category
Privilege Escalation
Content
```bash
docker run -d \
  --device /dev/kfd \
  --device /dev/dri \
  --group-add video \
  ollama/ollama:rocm
Confidence
87% confidence
Finding
Passing host device nodes such as '/dev/kfd' into a container materially increases host attack surface and weakens isolation. If the container image or workload is compromised, device access can enable deeper host interaction, data exposure, or kernel-driver attack paths.

Privileged Container / Container Escape

High
Category
Privilege Escalation
Content
```bash
docker run -d \
  --device /dev/kfd \
  --device /dev/dri \
  --group-add video \
  ollama/ollama:rocm
```
Confidence
87% confidence
Finding
Exposing '/dev/dri' to the container grants direct access to GPU/DRM interfaces and similarly reduces container isolation. In an installation guide for local inference this may be operationally necessary, but it remains a real security-sensitive instruction that should be clearly caveated.

Missing User Warnings

High
Confidence
98% confidence
Finding
The documentation provides a configuration snippet to disable privacy enforcement while only labeling it 'Not Recommended,' without clearly describing the consequences. Disabling context-boundary enforcement can permit sensitive data leakage across requests, plugins, or cloud routing paths and undermines the core privacy claims of the skill.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
cp memory/audit.log archive/cloud-era/$(date +%Y%m%d)/

# Start fresh Nirvana logs
rm memory/nirvana-metrics.json memory/nirvana-audit.log
```

### Migrate Cached Responses
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Missing User Warnings

High
Confidence
96% confidence
Finding
The schema advertises cloud model fallback without a clear user-facing warning that prompts, context, or derived data may be transmitted to external APIs. In a skill handling agent memory and identity files, omission of this warning materially increases the chance that operators will enable fallback without understanding the privacy consequences.

Intent-Code Divergence

High
Confidence
99% confidence
Finding
The comment says certain identity files are 'Never exported', but reconfigure() allows identityFilesNeverExport to be replaced, weakening or removing those protections entirely. Because isIdentityFile() relies solely on this mutable list, an attacker or unsafe caller can reconfigure the stripper to permit export of files that the documentation claims are permanently blocked.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding
Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding
Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The guide enables cloud fallback after presenting the system as 'thinking locally' and privacy-protective, but it does not prominently warn that queries may be transmitted to a third-party provider once fallback is enabled. This can mislead users into sending sensitive prompts or context off-host under the assumption that privacy guarantees still hold.

External Transmission

Medium
Category
Data Exfiltration
Content
docker-compose ps

# Check Ollama health
curl http://localhost:11434/api/tags
```

## Verify Installation
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The documentation includes destructive log removal commands without an explicit warning about data loss, retention obligations, or the need to confirm backups. Users may copy-paste the commands and permanently delete audit or metrics records needed for incident response, compliance, or troubleshooting.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The guide states that identity 'stays local, never exported' while the provided configuration explicitly enables cloud fallbacks to third-party providers. This creates a misleading privacy guarantee that could cause operators to deploy under false assumptions and inadvertently send sensitive data off-device.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The expected-results section claims 'Zero identity files exported' even though the migration path keeps cloud fallback enabled. This inconsistency can mislead users into believing the deployment is privacy-preserving when it may still transmit sensitive content to external providers.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
The success criteria require 'Zero identity files exported to third parties' despite the documented rollback and steady-state configurations allowing cloud fallback. This sets an unattainable or misleading compliance target and may conceal actual privacy exposure during operation.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
The README instructs users to run `docker run -d -p 11434:11434 ollama/ollama` without pinning the image to a specific tag or digest. This causes deployments to pull whatever image is current at execution time, creating a supply-chain and reproducibility risk if the upstream image changes unexpectedly or is compromised.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The description advertises optional cloud fallback but does not provide a prominent warning, at the point of introduction, that user prompts may be sent to third-party providers such as Anthropic, OpenAI, or Gemini. In a privacy-focused skill that markets 'AI sovereignty' and 'zero API keys required,' this omission is especially risky because users may reasonably assume all processing remains local and may disclose sensitive data under that assumption.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
The installation instructions run the `ollama/ollama` container without pinning a specific tag or immutable digest, so users may pull whatever image is current at execution time. This creates supply-chain risk because a future upstream image change, compromise, or breaking update could introduce malicious code or unsafe behavior into the local environment.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The skill states that any normal OpenClaw interaction will automatically route through Nirvana and that the plugin internally decides between local and cloud providers. Broad automatic interception of ordinary usage can cause users to invoke the skill without clear intent, increasing the chance that sensitive prompts are processed or forwarded in ways the user did not explicitly request.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
Automatic model download is enabled by default, which creates implicit outbound network activity and pulls code or model artifacts without an explicit user warning. While this is not necessarily malicious, it can violate operator expectations in restricted or sensitive environments and may introduce supply-chain or egress-governance concerns.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The schema enables cloud fallback but does not define sufficiently strict conditions for when local requests may be escalated to external providers. In an agent setting, ambiguous fallback behavior can cause prompts or context to be sent off-box more broadly than users expect, increasing risk of unintended data disclosure even if some privacy controls exist elsewhere in the schema.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The manifest explicitly advertises a 'cloud fallback optional' design but does not define any gating conditions, user-consent requirements, or data-classification limits for when local prompts may be sent to a remote provider. In a plugin that also claims privacy enforcement and reads sensitive agent state files, ambiguous fallback behavior can cause unintended exfiltration of prompts, memory, or identity-bearing context to external services.

Vague Triggers

Medium
Confidence
84% confidence
Finding
The plugin declares broad 'query-router' and 'decisionEngine' capabilities without clear scope boundaries, exclusions, or routing policy constraints. Because the same manifest also grants access to sensitive context files and response/memory integration, an overly broad router could intercept arbitrary user or agent queries and redirect them in ways that bypass expected privacy or trust boundaries.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The module-level documentation asserts a privacy boundary ('Removes identity before sending queries to cloud APIs'), but strip() returns the original context unchanged whenever enforceContextBoundary is false. In a security-sensitive context-stripper, this creates a fail-open path that can expose all context, including personal or identity-bearing data, to external services if configuration is absent, disabled, or tampered with.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The cloud execution path transmits user queries and stripped context to an external provider, creating a data egress channel for potentially sensitive information. Although a context stripper is used, this file provides no explicit consent gate, disclosure, or verification that stripping is sufficient before external transmission.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The plugin records raw query content into metrics, which can capture sensitive prompts, secrets, personal data, or proprietary information. Even if intended for observability, collecting full queries without minimization, consent, or clear controls increases privacy risk and broadens the impact of any log exposure or insider access.

Static analysis

No suspicious patterns detected.