Back to skill

Security audit

opencode-session-reader-cn

Security checks for vulnerabilities and agentic risk

Overview

This skill is a read-only OpenCode session viewer, but it can be invoked implicitly and can expose broad local conversation history and message contents.

Review this before installing if your OpenCode history may contain private prompts, code, command output, paths, or secrets. Prefer explicit invocation, approve a specific project and session before reading message bodies, and avoid querying account or control_account tables.

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

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
agents/openai.yaml:1
Finding
Implicit Invocation Enables Broad Access to Local OpenCode Conversation History## Vulnerability Details **File Location**: `agents/openai.yaml:1-7`; `SKILL.md:109-119`; `SKILL.md:155-163` **Vulnerability Type**: Excessive access to sensitive local session data **Risk Level**: Medium ### Vulnerable Code `agents/openai.yaml:1-7` ```yaml interface: display_name: "OpenCode Session Reader" short_description: "Query local OpenCode SQLite sessions safely." default_prompt: "Use $opencode-session-reader to list recent OpenCode sessions, then inspect message JSON for a target directory." policy: allow_implicit_invocation: true ``` `SKILL.md:109-119` ```bash **跨所有目录全量列出 session(带 project 信息)** ```bash sqlite3 -readonly "$DB_PATH" \ "SELECT s.id, s.title, s.directory, p.worktree, datetime(s.time_updated/1000,'unixepoch','localtime') as updated FROM session s LEFT JOIN project p ON s.project_id = p.id ORDER BY s.time_updated DESC LIMIT 50;" | column -t -s '|' ``` ``` `SKILL.md:155-163` ```bash **查看某 session 的消息内容** ```bash sqlite3 -readonly -json "$DB_PATH" \ "SELECT m.id, datetime(m.time_created/1000,'unixepoch','localtime') as created, m.data FROM message m WHERE m.session_id = 'your-session-id' ORDER BY m.time_created ASC;" ``` ``` ### Technical Analysis The skill is configured for implicit invocation while its default workflow lists local OpenCode sessions and inspects complete message JSON. The documented cross-directory query has no project or directory restriction, allowing the agent to enumerate sessions from all projects represented in the database. A subsequent query returns the complete `message.data` value for a selected session. SQLite read-only mode prevents database modification, but it does not limit disclosure. OpenCode conversation records may contain prompts, source code, command output, local paths, credentials pasted into messages, or other sensitive project information. The combination of broad e ...[truncated 1421 chars]
Remediation
## Remediation Suggestions 1. Set `allow_implicit_invocation` to `false` for this privacy-sensitive skill. 2. Require explicit user confirmation before opening the OpenCode database or reading message bodies. 3. Require the user to approve a specific project, directory, and session before querying content. 4. Apply project or directory restrictions directly in every session query instead of enumerating all projects by default. 5. Return only minimal session metadata initially. Place message-body retrieval behind a separate confirmation step. 6. Redact likely credentials, tokens, private keys, and other secrets before message data enters the model context or output. 7. Record the selected scope in the response so the user can verify which database, project, and session were accessed.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:90
Finding
Direct SQL String Substitution Can Expand the Scope of Read-Only Queries## Vulnerability Details **File Location**: `SKILL.md:90-96`; `SKILL.md:155-170`; `SKILL.md:174-182` **Vulnerability Type**: SQL injection through unparameterized identifiers and search terms **Risk Level**: Medium ### Vulnerable Code `SKILL.md:90-96` ```bash sqlite3 -readonly "$DB_PATH" \ "SELECT s.id, s.title, s.directory, datetime(s.time_updated/1000,'unixepoch','localtime') as updated FROM session s WHERE s.project_id = 'your-project-id' ORDER BY s.time_updated DESC LIMIT 20;" | column -t -s '|' ``` `SKILL.md:155-170` ```bash sqlite3 -readonly -json "$DB_PATH" \ "SELECT m.id, datetime(m.time_created/1000,'unixepoch','localtime') as created, m.data FROM message m WHERE m.session_id = 'your-session-id' ORDER BY m.time_created ASC;" ``` ```bash sqlite3 -readonly "$DB_PATH" \ "SELECT id, json_extract(data, '$.role') as role, time_created FROM message WHERE data LIKE '%keyword%' ORDER BY time_created DESC LIMIT 20;" | column -t -s '|' ``` `SKILL.md:174-182` ```bash sqlite3 -readonly "$DB_PATH" \ "SELECT id, title, directory, datetime(time_updated/1000,'unixepoch','localtime') as updated FROM session WHERE title LIKE '%keyword%' ORDER BY time_updated DESC LIMIT 20;" | column -t -s '|' ``` ### Technical Analysis The documented commands place project identifiers, session identifiers, and search terms directly inside SQL string literals. Users or implementing agents are expected to replace placeholders such as `your-session-id` and `keyword`. No parameter binding, strict identifier validation, or SQL-literal escaping is demonstrated. If a substituted value contains a quote and additional SQL syntax, it can terminate the intended string literal and alter the query structure. SQLite read-only mode prevents writes but does not prevent an attacker from weakening filters, adding compound queries, reading unrelated r ...[truncated 1663 chars]
Remediation
## Remediation Suggestions 1. Replace shell-level SQL interpolation with an audited wrapper that uses SQLite parameter binding. 2. Validate session and project identifiers against strict expected formats before querying. 3. Bind LIKE patterns as parameters and explicitly escape `%`, `_`, and the chosen escape character when literal matching is intended. 4. Enforce an allowlist of permitted tables, columns, and query templates. 5. Explicitly prohibit access to sensitive tables such as `account` and `control_account`. 6. Reject values containing control characters, statement delimiters, or unexpected quoting as defense in depth, while retaining parameter binding as the primary control. 7. Add tests using quotes, SQL comments, compound-query operators, `%`, and `_` to verify that supplied values cannot alter query structure or unexpectedly broaden searches.
Vulnerability Patterns
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (3)

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The natural-language description forces a specific language for users reading or invoking the skill metadata. Under the policy, language constraints should either be optional or explicitly justified; no user choice or justification is provided here.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The skill is primarily presented as a session/message/schema reader, but it explicitly notes that `account` and `control_account` tables contain sensitive credentials, normalizing access to a database that may store secrets. Even though it says to be careful and redact, the skill enables broad cross-directory database inspection and schema discovery, which increases the likelihood of credential exposure during routine use.

Natural-Language Policy Violations

Low
Confidence
97% confidence
Finding
The schema reference is written in Chinese throughout, and there is no indication that users may choose another language or that the file is intentionally limited to a Chinese-speaking audience. Under the stated policy, forcing a specific language without opt-in is a natural-language locale violation.

Static analysis

No suspicious patterns detected.