Back to skill

Security audit

Log Parser

Security checks for vulnerabilities and agentic risk

Overview

This is a straightforward local log parsing skill, with some reliability and documentation gaps but no hidden or purpose-mismatched behavior.

Install only if you are comfortable letting the skill read log files you explicitly provide. Avoid running it on very large logs or sharing its JSON output without reviewing and redacting secrets, personal data, internal hostnames, and session identifiers.

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/log_parser.py:90
Finding

Unbounded Whole-File Loading Enables Memory Exhaustion

Content
View full analysis

Vulnerability Details

File Location: scripts/log_parser.py, lines 90-113
Vulnerability Type: Uncontrolled resource consumption
Risk Level: Medium

Vulnerable Code

python
def parse_file(file_path: str, log_format: str = 'auto') -> Tuple[List[Dict], str]:
    """Parse entire log file"""
    entries = []
    detected_format = log_format
    
    try:
        with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
            lines = f.readlines()
    except FileNotFoundError:
        return [], ''
    
    if not lines:
        return [], ''
    
    # Auto-detect format
    if log_format == 'auto':
        # Try first few non-empty lines
        for line in lines[:10]:
            if line.strip():
                detected_format = detect_format(line)
                break
    
    for line in lines:
        entry = parse_line(line, detected_format)
        if entry:
            entries.append(entry)

Technical Analysis

readlines() loads the complete log file into an in-memory list. The function then creates an additional entries list containing parsed representations of the same data. No maximum file size, line count, parsed-entry count, or memory budget is enforced.

Consequently, memory consumption can substantially exceed the input file size because it includes the original strings, list overhead, parsed dictionaries, and individual field objects. A sufficiently large or continuously generated log snapshot can exhaust available memory.

Exploitation requires the attacker to control or influence the selected log file, or to convince an operator or automation workflow to process an oversized file.

Attack Path

  1. An attacker creates or expands a log file to a size that approaches or exceeds the available process memory.
  2. The attacker causes the parser to process that file through the --file argument.
  3. f.readlines() loads th ...[truncated 648 chars]
Remediation
View remediation

Remediation Suggestions

  • Replace readlines() with streaming iteration over the file.
  • Detect the format from a small, bounded prefix and then continue processing without retaining the original lines.
  • Aggregate statistics incrementally instead of storing all parsed entries when the selected action does not require them.
  • Enforce configurable limits on file size, line length, line count, and retained results.
  • Reject oversized files before parsing when the input is a regular file.
  • Return a controlled JSON error when a configured resource limit is exceeded.
  • Apply operating-system or container-level memory limits as defense in depth.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/log_parser.py:61
Finding

Non-Object JSON Entries Cause Unhandled Exceptions

Content
View full analysis

Vulnerability Details

File Location: scripts/log_parser.py, lines 61-69
Vulnerability Type: Improper input validation leading to denial of service
Risk Level: Medium

Vulnerable Code

python
def parse_line(line: str, log_format: str) -> Optional[Dict]:
    """Parse a single log line"""
    line = line.strip()
    if not line:
        return None
    
    if log_format == 'json':
        try:
            return json.loads(line)
        except:
            return None

The returned value is subsequently treated as a dictionary without type validation. Representative downstream operations include:

python
for entry in entries:
    field_counter.update(entry.keys())
python
for entry in entries:
    status = entry.get('status', 0)
    level = str(entry.get('level', '')).upper()

Technical Analysis

json.loads() can return any valid JSON type, including arrays, strings, numbers, booleans, and null. The parser's type annotation indicates that entries should be dictionaries, but this invariant is not enforced.

Downstream actions assume each accepted entry supports dictionary methods such as .keys() and .get(), or dictionary-style field membership. A valid JSON line such as [], 1, "text", or true can therefore cause an uncaught AttributeError or TypeError. Auto-detection also accepts these values as JSON because it only checks whether json.loads() succeeds.

The exception is not converted into the documented JSON error format, so the process exits unexpectedly and may expose a traceback depending on its execution environment.

Attack Path

  1. An attacker inserts a valid non-object JSON value into a log file, such as [].
  2. The parser is invoked with --format json, or auto-detection selects JSON from the crafted line.
  3. parse_line() accepts the value and adds it to entries.
  4. The operator selects an action such as `sta ...[truncated 655 chars]
Remediation
View remediation

Remediation Suggestions

  • Validate the result of json.loads() before returning it:
python
if log_format == 'json':
    try:
        value = json.loads(line)
    except (json.JSONDecodeError, TypeError):
        return None

    if not isinstance(value, dict):
        return None

    return value
  • Prefer specific exception types instead of bare except clauses.
  • Define and enforce an expected schema for JSON log objects, including allowed field types.
  • Reject malformed entries with a controlled error or skip them while recording a parse-failure count.
  • Add a top-level exception boundary that always emits structured JSON without exposing tracebacks.
  • Add tests covering JSON arrays, strings, numbers, booleans, null, deeply nested values, and mixed-validity files for every supported action.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (3)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README presents all descriptive and usage content in Chinese, and does not indicate that the skill is region-specific or provide any user language choice. This can violate language/locale policy when users are not explicitly opted into Chinese-only interaction.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill invokes a local Python script that reads arbitrary user-supplied log files via the --file argument, but the manifest does not declare any tool scope or permissions for file access. This creates a mismatch between documented capability and declared security boundaries, which can lead to unintended access to sensitive local files and weakens policy enforcement or review of the skill's behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The skill is designed to parse logs and emit structured JSON, but the documentation does not warn that logs commonly contain sensitive data such as IPs, usernames, URLs, tokens, session identifiers, or internal hostnames. Users may unintentionally expose or over-share parsed output, especially when using filtering, top-N summaries, or error extraction in collaborative or automated contexts.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.