Back to skill

Security audit

Log Analyzer

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent local log-analysis skill, but users should treat analyzed logs and generated reports as potentially sensitive and untrusted.

Install only if you are comfortable giving the skill access to the log files or directories you choose. Avoid running it on broad or sensitive log trees without review, prefer JSON/text handling over rendering Markdown from untrusted logs, and be careful before wiring it into CI or cron because its exit codes and reports can affect operational workflows.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/analyze_logs.py:552
Finding

Terminal Control-Sequence Injection Through Untrusted Log Messages

Content
View full analysis

Vulnerability Details

File Location: scripts/analyze_logs.py, lines 552–555 and 742
Vulnerability Type: Terminal output injection
Risk Level: Medium

Vulnerable Code

python
for i, p in enumerate(result['patterns'], 1):
    sev = p['severity_label']
    out.append(f'[{sev}] #{i} — {p["count"]:,}x occurrences')
    out.append(f'  Message: {p["message"][:200]}')

The resulting report is subsequently written directly to the terminal:

python
formatter = formatters.get(args.output, format_text)
print(formatter(result, args))

Technical Analysis

Log messages are untrusted input because external clients, remote services, request parameters, user-agent strings, and other attacker-controlled values are commonly copied into application logs. The text formatter includes these messages in its output without removing ANSI escape sequences or other terminal control characters.

The 200-character truncation does not provide sanitization. A malicious control sequence can fit within this limit and may alter colors, move the cursor, overwrite visible content, hide subsequent findings, forge prompts, or manipulate terminal presentation. The exact behavior depends on the terminal emulator. The code does not independently establish arbitrary command execution, but it does permit manipulation of report integrity and the analyst's terminal display.

Attack Path

  1. An attacker submits input containing ANSI escape sequences or other terminal control characters to an application whose logs will be analyzed.
  2. The target application records the attacker-controlled value in a warning, error, or fatal log message.
  3. An analyst invokes analyze_logs.py against the affected log.
  4. The analyzer retains the control characters in LogEntry.message.
  5. format_text() inserts the message into the report without sanitization.
  6. print() sends the resulting control sequences to the analyst's terminal.
  7. The terminal interprets those ...[truncated 470 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove ANSI escape sequences and unsafe control characters before inserting log data into terminal reports.
  • Permit only expected whitespace controls such as newline and tab where they are structurally necessary.
  • Apply sanitization to every attacker-controlled field, including messages, source names, and recommendations derived from input.
  • Consider rendering nonprintable characters using visible escaped notation such as \x1b.
  • Keep the raw value only in a separate, explicitly requested machine-readable output if required for forensic analysis.
  • Add tests containing escape characters, cursor-control sequences, carriage returns, backspaces, and bidirectional Unicode controls.

Example hardening approach:

python
ANSI_ESCAPE_RE = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')

def sanitize_terminal(value):
    value = ANSI_ESCAPE_RE.sub('', str(value))
    return ''.join(
        ch if ch in '\n\t' or ord(ch) >= 32 else repr(ch)[1:-1]
        for ch in value
    )

Apply this function before adding any untrusted value to terminal output.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/analyze_logs.py:653
Finding

Markdown Report Injection Through Unescaped Log Messages

Content
View full analysis

Vulnerability Details

File Location: scripts/analyze_logs.py, lines 653–656
Vulnerability Type: Markdown content injection
Risk Level: Medium

Vulnerable Code

python
for i, p in enumerate(result['patterns'], 1):
    sev = p['severity_label']
    out.append(f'### {i}. [{sev}] {p["count"]:,}x — {p["message"][:120]}')
    if p['sources']:
        out.append(f'**Sources:** {", ".join(p["sources"])}')

Technical Analysis

The Markdown formatter places attacker-controlled log messages and source values directly into Markdown syntax without escaping Markdown metacharacters or embedded HTML. Truncating the message to 120 characters does not prevent injection because links, images, headings, and compact HTML constructs can fit within this limit.

A crafted message can alter report structure, insert deceptive links, create externally loaded image references, or inject HTML accepted by permissive Markdown renderers. The analyzer itself does not make network requests, but a downstream Markdown viewer may retrieve attacker-selected image or link resources when rendering the generated report.

Attack Path

  1. An attacker causes a crafted Markdown or HTML fragment to appear in an application log.
  2. The logged entry meets the configured severity threshold.
  3. An analyst generates a report using --output markdown.
  4. format_markdown() inserts the malicious message into a heading without escaping it.
  5. The report is opened in a Markdown renderer.
  6. The injected syntax changes the report's appearance or presents attacker-controlled links or resources.
  7. A reviewer may be misled into following a malicious link, or a permissive renderer may request an attacker-controlled external resource.

Impact Assessment

The vulnerability compromises the integrity of generated reports and can facilitate phishing or deceptive remediation instructions. Depending on the downstream Markdown renderer, it may also expose renderer metadata ...[truncated 155 chars]

Remediation
View remediation

Remediation Suggestions

  • Escape Markdown metacharacters in every untrusted field before inserting it into a report.
  • Escape or remove embedded HTML rather than relying on the downstream renderer to disable it.
  • Render log messages inside fenced code blocks while safely handling embedded fence delimiters.
  • Sanitize source names as well as messages.
  • Document that reports contain untrusted data and recommend renderers that disable raw HTML and remote resource loading.
  • Add tests for headings, links, images, HTML tags, code fences, tables, and bidirectional Unicode controls.

A dedicated escaping function should cover at least backslashes, backticks, asterisks, underscores, braces, brackets, parentheses, angle brackets, hash symbols, plus signs, hyphens, periods, exclamation marks, and pipe characters.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/analyze_logs.py:406
Finding

Memory Exhaustion Through Unbounded Whole-File Log Loading

Content
View full analysis

Vulnerability Details

File Location: scripts/analyze_logs.py, lines 406–414
Vulnerability Type: Uncontrolled resource consumption
Risk Level: Medium

Vulnerable Code

python
def read_log_file(filepath):
    """Read a log file, handling common encodings."""
    for enc in ['utf-8', 'latin-1', 'ascii']:
        try:
            with open(filepath, 'r', encoding=enc, errors='replace') as f:
                return f.readlines()
        except (UnicodeDecodeError, PermissionError):
            continue
    return []

Technical Analysis

readlines() loads the complete selected file into memory. The caller then creates additional strings, LogEntry objects, normalized messages, grouping lists, counters, and report structures from this data. Consequently, peak memory consumption can substantially exceed the original file size.

When a directory is supplied, collect_files() recursively identifies multiple matching log files. Each file is read in full before parsing, and parsed entries from every file remain in the global all_entries list. There is no limit on input size, file count, line length, entry count, or aggregate memory consumption.

An attacker who can influence log volume can therefore create an oversized log or many matching files. Even without an attacker, ordinary production logs may be large enough to exhaust memory.

Attack Path

  1. An attacker repeatedly submits requests or values that generate large warning or error log entries, or otherwise gains the ability to place an oversized file in a scanned log directory.
  2. An analyst runs the analyzer against the affected file or directory.
  3. read_log_file() calls readlines() and allocates memory for the complete file.
  4. Parsing creates additional objects and retains them in all_entries.
  5. Grouping and formatting allocate further structures based on the retained entries.
  6. The process exceeds its memory allowance, becomes unresponsive, is terminat ...[truncated 430 chars]
Remediation
View remediation

Remediation Suggestions

  • Parse files incrementally with an iterator instead of readlines().
  • Avoid retaining every parsed entry; update bounded counters and pattern summaries while streaming.
  • Add configurable limits for:
    • Maximum individual file size
    • Maximum aggregate input size
    • Maximum number of files
    • Maximum line length
    • Maximum parsed entries
    • Maximum unique fingerprints
    • Maximum retained samples per fingerprint
  • Reject or require explicit confirmation for inputs exceeding safe defaults.
  • Use bounded collections for sample lines and trend data.
  • Handle oversized lines without allocating the complete value where possible.
  • Report skipped or truncated data clearly so analysts know the report is incomplete.
  • Consider resource limits at deployment time as defense in depth.

A streaming structure should resemble:

python
with open(filepath, 'r', encoding='utf-8', errors='replace') as f:
    for line_num, line in enumerate(f, 1):
        if line_num > max_entries:
            break
        process_line(line, line_num)

The implementation should aggregate results as each line is processed instead of appending every entry to all_entries.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The trigger list includes broad troubleshooting phrases like "what's failing" and "production errors," which can cause the skill to activate in situations beyond narrow log-analysis intent. Overbroad activation increases the chance that sensitive logs or incident context are pulled into this skill unnecessarily, creating data exposure and workflow-confusion risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The script stores a sample_raw slice from parsed log entries, which may contain secrets, personal data, tokens, or internal paths commonly present in logs. Although the tool description explains that it analyzes logs, it does not disclose that raw log content may be surfaced in output or retained in result structures.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The skill documentation encourages use in CI/CD pipelines to fail builds on detected errors and as a cron job for automated daily reports, but it does not include any warning that logs may contain sensitive information or that automation can affect operational workflows. For markdown files, behaviors that may affect user data or system integrity should be accompanied by a user-facing warning.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
71% confidence
Finding

All user-facing natural-language descriptions, headings, and recommendations are hard-coded in English, with no indication that users can choose another language or locale. Under the stated policy, forcing a specific language without opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.