Back to skill

Security audit

OpenCode Session Toolkit 中文

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent and not malicious, but it can read and export sensitive local OpenCode conversations and has automatic invocation enabled, so it should be reviewed before installation.

Install only if you want an agent to inspect local OpenCode session history. Avoid implicit use for broad questions, review the resolved database path and selected sessions before `show` or `export`, and use `--include-sensitive` only when you are prepared for raw prompts, reasoning, tool payloads, and accidental secrets to appear in terminal output or saved files.

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

other

Warning
Location
scripts/opencode_sessions.py:547
Finding

Sensitive Local Conversation and Tool Payload Disclosure

Content
View full analysis

Vulnerability Details

File Location: scripts/opencode_sessions.py:547-596, scripts/opencode_sessions.py:680-718, and scripts/opencode_sessions.py:1002-1018
Vulnerability Type: Sensitive local conversation access
Risk Level: Medium

Complete Code Snippet

python
def load_transcript(
    connection: sqlite3.Connection,
    capabilities: Capabilities,
    session_id: str,
) -> list[MessageRecord]:
    require_capability(capabilities, "message")
    require_capability(capabilities, "part")
    message_rows = connection.execute(
        """
        SELECT id, time_created, data
        FROM message
        WHERE session_id = ?
        ORDER BY time_created ASC, id ASC
        """,
        (session_id,),
    ).fetchall()
    messages: list[MessageRecord] = []
    by_id: dict[str, MessageRecord] = {}
    for row in message_rows:
        raw = str(row["data"])
        payload = safe_json_loads(raw)
        message = MessageRecord(
            id=str(row["id"]),
            created_ms=int(row["time_created"]),
            role=str((payload or {}).get("role") or "unknown"),
            model_id=string_or_none((payload or {}).get("modelID")),
            provider_id=string_or_none((payload or {}).get("providerID")),
            payload=payload,
            raw_data=raw,
        )
        messages.append(message)
        by_id[message.id] = message

    for row in connection.execute(
        """
        SELECT id, message_id, time_created, data
        FROM part
        WHERE session_id = ?
        ORDER BY message_id ASC, time_created ASC, id ASC
        """,
        (session_id,),
    ):
        message = by_id.get(str(row["message_id"]))
        if message is None:
            continue
        raw = str(row["data"])
        payload = safe_json_loads(raw)
        message.parts.append(
            PartRecord(
                id=str(row["
...[truncated 4236 chars]
Remediation
View remediation

Remediation Suggestions

  1. Require a separate interactive confirmation immediately before reading or exporting complete payloads. Show the resolved database path, selected session IDs, destination, and categories of sensitive fields first.
  2. Refuse --include-sensitive in non-interactive execution unless a second explicit acknowledgement flag is supplied.
  3. Add default redaction for common secret patterns and fields, including tokens, API keys, authorization headers, passwords, cookies, and private keys.
  4. Allow users to select specific payload fields instead of exposing complete raw message and part objects.
  5. Disable implicit Skill invocation for sensitive transcript operations or require explicit user authorization before show and export.
  6. Create export files with restrictive owner-only permissions and verify destination-directory permissions before writing.
  7. Emit a clear warning that standard output may be captured by shell history, CI logs, agent traces, or downstream tools.
  8. Provide a metadata-only preview that lists selected sessions and estimated disclosure scope before transcript data is loaded.
  9. Preserve the existing read-only SQLite protections, parameterized queries, full-export acknowledgement, and overwrite safeguards.
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (5)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill invokes local file reads and shell execution via ./scripts/opencode_sessions.py, but it does not declare any explicit tool scope such as permissions or allowed-tools. That omission weakens policy enforcement and can cause the runtime to grant broader-than-intended capabilities, especially since the skill operates over cross-project local SQLite session data that may contain sensitive transcripts.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The display name, description, and default prompt are all specified in Chinese, with no indication that the user can choose another language or locale. This can violate language or locale policy when a skill imposes a specific language without explicit opt-in or documented regional justification.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill enables implicit invocation without any visible trigger constraints, which can cause the agent to auto-select a tool that accesses local SQLite session data even when the user did not clearly request it. In a skill designed to inspect, search, and export local cross-project OpenCode sessions, this increases the chance of unintended data exposure or over-broad tool use.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file presents all operational instructions exclusively in Chinese and does not indicate that users may choose another language. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is documented and justified.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/opencode_sessions.py (reported line 268)May include surrounding context.

python
path = Path(explicit_path).expanduser().resolve()
    else:
        try:
            result = subprocess.run(
                ["opencode", "db", "path"],
                check=True,
                capture_output=True,

Static analysis

No suspicious patterns detected.