Back to skill

Security audit

Bonds

Security checks for vulnerabilities and agentic risk

Overview

This is a Review item because it is advertised as a bond analysis tool but behaves mostly like a broad local logger for potentially sensitive financial text.

Review before installing if you may enter sensitive portfolio details. This skill stores raw text locally and does not actually perform the advertised bond calculations, so use it only if a simple local logger is acceptable and the local machine is trusted.

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

Potential Exposure of Sensitive Financial Records Through Ambient File Permissions

Content
View full analysis

Vulnerability Details

File Location: scripts/script.sh, lines 5–9
Vulnerability Type: Sensitive data stored without enforced restrictive permissions
Risk Level: Medium

Vulnerable Code

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

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

User-supplied records are also written to command-specific files without enforcing their permissions. Representative code from lines 124–136 is:

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: bonds 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 "  [Bonds] run: $input"
        echo "  Saved. Total run entries: $total"
        _log "run" "$input"
    fi

The same storage pattern occurs for the other record commands at lines 144–296.

Technical Analysis

The application is intended to store bond holdings and other potentially sensitive financial information under ~/.local/share/bonds. It creates the data directory with mkdir -p and creates log files through shell redirection, but it does not set a restrictive umask or explicitly enforce directory and file modes.

Consequently, the actual permissions depend on the environment's inherited umask. With a permissive umask, the directory or its files may be readable by other local users. In addition, _log duplicates each submitted value in history.log, increasing the number of files containing the sensitive information.

This is not an unconditional disclosure: exploitation requires another local account to have filesystem traversal and read access resulting from the effective permi ...[truncated 926 chars]

Remediation
View remediation

Remediation Suggestions

  • Set a restrictive process mask before creating or writing any data:

    bash
    umask 077
    
  • Create and enforce the data-directory mode explicitly:

    bash
    install -d -m 700 "$DATA_DIR"
    
  • Create data files with mode 600, and correct existing permissions where appropriate:

    bash
    touch "$DATA_DIR/history.log"
    chmod 600 "$DATA_DIR/history.log"
    
  • Apply the same file-mode enforcement to every command-specific log.

  • Avoid duplicating complete sensitive values in history.log; record only the action type and timestamp unless the duplicate content is required.

  • Document the sensitivity and retention policy of the locally stored records.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/script.sh:104
Finding

Stored Terminal Control-Sequence Injection Through Unsanitized Records

Content
View full analysis

Vulnerability Details

File Location: scripts/script.sh, lines 104–120 and 124–136
Vulnerability Type: Stored terminal output injection
Risk Level: Low

Vulnerable Code

bash
_search() {
    local term="${1:?Usage: bonds search <term>}"
    echo "Searching for: $term"
    for f in "$DATA_DIR"/*.log; do
        [ -f "$f" ] || continue
        local m=$(grep -i "$term" "$f" 2>/dev/null || true)
        if [ -n "$m" ]; then
            echo "  --- $(basename "$f" .log) ---"
            echo "$m" | sed 's/^/    /'
        fi
    done
}

_recent() {
    echo "=== Recent Activity ==="
    tail -20 "$DATA_DIR/history.log" 2>/dev/null | sed 's/^/  /' || echo "  No activity yet."
}

A representative record-storage path is:

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: bonds 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 "  [Bonds] run: $input"
        echo "  Saved. Total run entries: $total"
        _log "run" "$input"
    fi

Technical Analysis

Command arguments are accepted as arbitrary text and persisted verbatim in command logs and history.log. The no-argument command views, _search, and _recent subsequently send stored content directly to the terminal. Prefixing content with sed does not remove terminal control characters.

A crafted value can therefore contain ANSI or OSC sequences. When a user later displays the record in a compatible terminal, the terminal interprets those bytes rather than rendering them as inert text. Depending on terminal capabilities and policy, such sequences can change colors, clear or overwrite displayed text, alter window titles, create dece ...[truncated 1407 chars]

Remediation
View remediation

Remediation Suggestions

  • Reject disallowed control characters when records are accepted, while preserving only the explicitly supported whitespace characters.

  • Alternatively, encode untrusted values before displaying them so that escape bytes are visible rather than interpreted.

  • Use a dedicated rendering function for every path that prints stored data, including search results, recent activity, and command-specific history.

  • A shell-oriented escaped representation can be produced with printf '%q', although a user-friendly application may prefer explicit hexadecimal or Unicode escape notation.

  • Validate search terms and pass -- before the pattern to prevent values beginning with a hyphen from being interpreted as grep options:

    bash
    grep -i -- "$term" "$f"
    
  • Add tests containing ESC, BEL, carriage return, backspace, and multiline values to confirm that terminal output remains inert and structurally trustworthy.

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

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is presented as a bond portfolio utility, but its documented behavior includes broad generic command capture, activity logging, status inspection, and exporting/searching log contents unrelated to bonds. This mismatch is dangerous because users may provide sensitive financial or operational input under a narrow trust assumption, while the skill appears designed to retain and expose a wider class of data than advertised.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest says this skill should record bond holdings, analyze yields, track maturity dates, compare yields, and export bond data. Instead, the help text exposes generic commands and the rest of the script merely appends arbitrary user input to per-command log files, with no bond-specific parsing, holdings model, yield calculations, or maturity tracking.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

Handlers for analyze, compare, report, status, and export simply timestamp input and write it to log files, then echo confirmation. This behavior does not match a skill described as managing fixed-income portfolios or analyzing bond yields, because there is no actual financial computation, bond record handling, or maturity-date logic in these command implementations.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The command list uses vague verbs like run, check, convert, generate, preview, and batch without defining inputs, side effects, or data handling. Unclear activation scope increases the risk of over-collection, unsafe invocation, or misuse by agents and users who cannot tell whether a command performs benign analysis or broad data capture/export.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The tool is architected to persist and later re-display essentially all user-provided content through logs, status views, search, recent history, and exports. Because the skill is presented as a bond/portfolio utility, the captured data is more likely to include sensitive financial information, increasing the privacy and disclosure risk beyond a generic toy logger.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

Commands such as run, convert, generate, preview, batch, and config are broad utility actions with no evident connection to recording bond holdings or analyzing fixed-income portfolios. Their implementations also just persist arbitrary text, suggesting a repurposed generic toolkit rather than functionality needed for the manifest's stated domain.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The export function aggregates historical logs into json, csv, or txt files on disk, potentially duplicating sensitive financial data into additional locations without warning or access controls. In a bond-management context, exported files can contain complete activity history and be easier to share, copy, or inadvertently disclose than the original logs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script persistently stores raw user-supplied input in local log files without notice, minimization, or sensitivity controls. In the context of a finance-related skill, users may enter holdings, account identifiers, or other sensitive portfolio notes that can later be exposed to other local users, backups, or support processes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill highlights offline/local storage benefits but does not prominently warn that all actions are automatically logged with timestamps. For financial workflows, silent local logging can capture sensitive holdings, search terms, and analysis history that users may not expect to be retained, increasing privacy and confidentiality risk on shared or compromised systems.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.