Back to skill

Security audit

Context Visualization

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but it reads and inventories agent memory files by default, which is broader than a simple context-usage view.

Review this before installing if your workspace memory/ directory may contain private notes or sensitive records. The skill does not appear to transmit or persist data, but it will process local memory files to produce estimates; use it only on workspaces where that local inspection is acceptable.

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

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/estimate_tokens.py:30
Finding

Unrestricted Recursive Reading of Agent Memory Files

Content
View full analysis

Vulnerability Details

File Location: scripts/estimate_tokens.py, lines 30-65 and 89-91
Vulnerability Type: Excessive file access and insufficient path containment
Risk Level: Medium

Vulnerable Code

python
def scan_memory_dir(workspace: str):
    """Scan memory/ directory for all files, grouped by type."""
    memory_dir = os.path.join(workspace, "memory")
    if not os.path.isdir(memory_dir):
        return [], 0, 0

    entries = []
    total_tokens = 0
    total_bytes = 0

    for root, dirs, files in os.walk(memory_dir):
        # Skip hidden dirs
        dirs[:] = [d for d in dirs if not d.startswith('.')]
        for fname in sorted(files):
            if fname.startswith('.'):
                continue
            fpath = os.path.join(root, fname)
            rel = os.path.relpath(fpath, workspace)
            try:
                size = os.path.getsize(fpath)
                total_bytes += size
                # Estimate tokens for text files only
                if fname.endswith(('.md', '.json', '.txt', '.yaml', '.yml')):
                    with open(fpath, 'r', encoding='utf-8', errors='replace') as f:
                        content = f.read()
                    tokens = estimate_tokens(content)
                else:
                    tokens = 0  # binary files
                total_tokens += tokens
                entries.append({
                    "path": rel,
                    "bytes": size,
                    "tokens": tokens,
                })
            except (OSError, IOError):
                continue

    return entries, total_tokens, total_bytes
python
    # Memory files (NOT in context, but useful inventory)
    mem_entries, mem_tokens, mem_bytes = scan_memory_dir(workspace)

Technical Analysis

The script accepts a caller-controlled workspace path and recursively traverses its memory/ directory. It opens every non-hidden file with a supported text extension and reads the enti ...[truncated 2511 chars]

Remediation
View remediation

Remediation Suggestions

  1. Avoid reading memory contents by default. Use os.stat() or Path.stat() to report file counts and byte sizes. If token estimation requires content access, make it an explicit opt-in operation with a clear privacy warning.

  2. Canonicalize and validate the workspace root. Resolve the supplied workspace before traversal:

python
workspace_root = Path(workspace).resolve(strict=True)
memory_root = (workspace_root / "memory").resolve(strict=True)
memory_root.relative_to(workspace_root)
  1. Enforce containment for every file. Resolve each candidate and reject it unless it remains under memory_root:
python
candidate = Path(root, fname)

if candidate.is_symlink():
    continue

resolved = candidate.resolve(strict=True)
try:
    resolved.relative_to(memory_root)
except ValueError:
    continue
  1. Skip symbolic links. Use os.lstat() or Path.is_symlink() before size checks and file opening. Where supported, use no-follow semantics and verify the opened file descriptor to reduce time-of-check/time-of-use risks.

  2. Apply resource limits. Limit maximum file size, total bytes read, and traversal depth to prevent memory exhaustion or denial of service from unusually large files or directory trees.

  3. Handle decoding consistently. The top-level workspace files are opened without errors='replace', while memory files use replacement behavior. Apply explicit error handling so malformed input cannot unexpectedly terminate the audit operation.

  4. Document the data-access boundary. Clearly state whether the Skill performs metadata-only inventory or content-based estimation, and require user confirmation before processing long-term Agent memory.

Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (2)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill promises a trustworthy visualization of current context usage, but its method relies on rough heuristics, a fixed system-overhead estimate, and inferred message-token residuals rather than measuring the claimed components directly. That mismatch can mislead users about actual context occupancy and also encourages inventorying files under memory/, expanding data exposure beyond the narrowly described purpose and potentially revealing sensitive file names, categories, or approximate sizes.

Content

No source excerpt is available for this finding.

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.

Static analysis

No suspicious patterns detected.