Back to skill

Security audit

Trivia

Security checks for vulnerabilities and agentic risk

Overview

This is a generic local activity logger packaged as a trivia skill, so users should review it before installing because it can retain and later surface whatever text is entered.

Install only if you intentionally want a local plaintext activity log, not a full trivia engine. Do not enter secrets, API keys, personal data, private answer keys, or sensitive business content; review and clean ~/.local/share/trivia if you use it, and consider tightening file permissions before storing anything important.

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

Warning
Location
scripts/script.sh:5
Finding

Plaintext Activity Logs Are Created Without Restrictive Permissions

Content
View full analysis

Vulnerability Details

File Location: scripts/script.sh:5-8; representative data write at scripts/script.sh:125-132
Vulnerability Type: Insecure local storage and insufficient file-permission hardening
Risk Level: Medium

Vulnerable Code

bash
DATA_DIR="${HOME}/.local/share/trivia"
mkdir -p "$DATA_DIR"

_log() { echo "$(date '+%m-%d %H:%M') $1: $2" >> "$DATA_DIR/history.log"; }

Representative storage of user-controlled content:

bash
    run)
        shift
        if [ $# -eq 0 ]; then
            echo "Recent run entries:"
            tail -20 "$DATA_DIR/run.log" 2>/dev/null || echo "  No entries yet. Use: trivia run <input>"
        else
            local input="$*"
            local ts=$(date '+%Y-%m-%d %H:%M')
            echo "$ts|$input" >> "$DATA_DIR/run.log"

Technical Analysis

The script persistently records user-provided task descriptions, configuration entries, reports, and other command arguments in plaintext files under ~/.local/share/trivia/. It creates the directory with mkdir -p and creates log files through shell redirection, but it does not establish a restrictive umask or explicitly set directory and file permissions.

Consequently, effective permissions depend on the invoking process's ambient umask. With a permissive configuration, other local users or processes may be able to read the stored content. The Skill documentation encourages recording configuration changes and general workflow data, which could include confidential project names, paths, answer keys, operational details, or accidentally supplied credentials.

This issue does not itself provide remote access, privilege escalation, or code execution. Exploitation requires local filesystem access and permissions that allow the attacker to read the generated files.

Attack Path

  1. A user invokes a command such as trivia config, trivia report, or trivia run with sensitive con ...[truncated 874 chars]
Remediation
View remediation

Remediation Suggestions

  • Set a restrictive umask before creating any storage:

    bash
    umask 077
    
  • Create and validate the data directory with owner-only permissions:

    bash
    install -d -m 0700 "$DATA_DIR"
    
  • Create log files with mode 0600, and correct permissions on existing files:

    bash
    touch "$DATA_DIR/history.log"
    chmod 0600 "$DATA_DIR/history.log"
    
  • Apply equivalent protection to every command-specific log and generated export.

  • Refuse to use the path if it is a symbolic link or is owned by another user.

  • Document that users should not submit credentials, API keys, tokens, or other secrets.

  • Consider configurable retention limits and a secure command for deleting historical records.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/script.sh:125
Finding

Unescaped Newlines Permit Activity Log Record Forgery

Content
View full analysis

Vulnerability Details

File Location: scripts/script.sh:125-132; equivalent patterns appear in the other command branches through line 288
Vulnerability Type: Log injection and audit-record integrity failure
Risk Level: Low

Vulnerable Code

bash
    run)
        shift
        if [ $# -eq 0 ]; then
            echo "Recent run entries:"
            tail -20 "$DATA_DIR/run.log" 2>/dev/null || echo "  No entries yet. Use: trivia run <input>"
        else
            local input="$*"
            local ts=$(date '+%Y-%m-%d %H:%M')
            echo "$ts|$input" >> "$DATA_DIR/run.log"
            local total=$(wc -l < "$DATA_DIR/run.log")
            echo "  [Trivia] run: $input"
            echo "  Saved. Total run entries: $total"
            _log "run" "$input"
        fi

The shared history logger also writes the same unescaped input:

bash
_log() { echo "$(date '+%m-%d %H:%M') $1: $2" >> "$DATA_DIR/history.log"; }

Technical Analysis

User-controlled command arguments are appended directly to line-oriented log files. No validation or encoding prevents newline, carriage-return, pipe-delimiter, or other control characters from entering a record.

A single argument containing embedded newline characters can therefore create multiple physical lines in both the command-specific log and history.log. The additional lines can resemble legitimate records, corrupt record counts, or mislead users reviewing recent, search, stats, and raw log output.

The pipe character can also alter the intended timestamp|value field structure used by the export implementation. Although shell metacharacters in the value are not evaluated as commands in the shown write operations, the lack of structured escaping compromises the integrity of the purported audit trail.

Attack Path

  1. An attacker or untrusted caller supplies a multiline argument, for example:

    bash
    triv
    

...[truncated 939 chars]

Remediation
View remediation

Remediation Suggestions

  • Reject newline, carriage-return, NUL, and other disallowed control characters before logging user input.

  • Do not use ad hoc line- and pipe-delimited records for untrusted values.

  • Serialize each record using a format with correct escaping, such as JSON Lines generated by a trusted JSON encoder.

  • If the delimiter format must be retained, escape backslashes, delimiters, carriage returns, and newlines consistently during writing, and decode them only during display.

  • Use printf rather than echo for predictable output behavior:

    bash
    printf '%s|%s\n' "$ts" "$encoded_input" >> "$DATA_DIR/run.log"
    
  • Add tests covering multiline arguments, pipe characters, terminal control sequences, Unicode separators, and malformed records.

  • Treat existing logs as untrusted when displaying them; remove or visibly encode terminal control characters to prevent deceptive console output.

Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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
Findings (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill is presented as a trivia/quiz utility, but the documented behavior is a generic logging and data-processing toolkit that persistently stores arbitrary user inputs and supports search/export/reporting over them. This mismatch is dangerous because users or calling agents may grant it access under a narrow trivia-related trust model while it actually performs broader data collection and retention, increasing the chance of unintended capture and exposure of sensitive data.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The manifest and description claim a trivia quiz skill, but the body documents a generic local data-processing and logging system. In an agent ecosystem, this kind of semantic deception can cause inappropriate activation and trust decisions, leading the agent or user to provide arbitrary content that is then stored, searched, and exported outside the expected trivia context.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The manifest describes quiz-specific functionality such as question banks, answer checking, scoring, boards, and round generation. In contrast, the help text and command handlers expose generic verbs like run, convert, batch, compare, config, and report, and the implementation merely appends arbitrary input strings to per-command log files rather than performing trivia logic.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The usage scope is so broad that an agent may activate this skill for many unrelated tasks, despite its branding as trivia-focused. Overbroad activation expands the chance that sensitive or irrelevant user inputs are routed into a tool that logs them locally and later exposes them through search, recent-history, or export features.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The title and examples create a trivia framing, while the command descriptions describe broad task execution and data processing. That inconsistency can mislead users and orchestration logic about when the skill should be invoked and what kinds of inputs are safe to provide, making unintended data persistence and misuse more likely.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill states that all inputs are stored locally and can be exported, but it does not prominently warn users that invoking commands creates persistent files and retains their content. This is dangerous because users may provide quiz content, answers, names, or other sensitive data without realizing it will be written to disk and surfaced through later export or search operations.

Content

No source excerpt is available for this finding.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill grants unrestricted tool access without appropriate constraints. An agent with unfettered tool access can perform arbitrary actions including file modification, network requests, and code execution.

Content

Scanner excerpt · SKILL.md (reported line 146)May include surrounding context.

md
## Tips

- Every command with input is automatically timestamped — your full history is preserved
- Run any command without arguments to review its last 20 entries
- Use `stats` for a bird's-eye view of entry counts across all command types
- Export supports `json` (structured), `csv` (spreadsheets), and `txt` (human-readable) formats
- All log files are plain text — you can grep, edit, or pipe them directly

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script persistently stores all user-supplied command inputs under ~/.local/share/trivia without consent prompts, minimization, or sensitivity warnings. In a skill context, users may provide trivia content, answers, participant names, API tokens, or other sensitive text, which then becomes recoverable from local files and exports long after use.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The help output advertises status as a health check, and _status is implemented to show version, data directory, entry counts, disk usage, and last activity. But the earlier status) branch at L273-L287 handles the command first and merely appends user input to status.log, making the actual status command at L307 unreachable.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The help text says export <fmt> performs an actual export, and there is a dedicated _export function for that purpose. However, the first export) branch at L243-L257 consumes the command and only records arbitrary input to export.log, so the real exporter at L304 is unreachable and the documented behavior is contradicted by execution.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Commands such as convert, config, status, batch, compare, and report are implemented as plain input-capture/logging actions with no evident tie to trivia rounds, score analysis, or quiz management. These behaviors expand the skill into a catch-all utility interface beyond what the manifest says it is for.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.