Back to skill

Security audit

Auto Log

Security checks for vulnerabilities and agentic risk

Overview

This skill is a straightforward local daily logging helper, with privacy and hardening notes around what gets persisted to disk.

Before installing, choose a private memory_dir, avoid logging secrets or sensitive prompts, periodically review or delete retained logs, and ensure any agent that reads these files treats them only as historical data, not executable instructions.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • 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)

T02 · Agent Memory Poisoning

Warning
Location
auto_log_skill.py:95
Finding
Persistent Agent Memory Poisoning Through Unescaped Log Entries<![CDATA[ ## Vulnerability Details **File Location**: `auto_log_skill.py:95-124`, `auto_log_skill.py:135-161`, and `auto_log_skill.py:175-201` **Vulnerability Type**: Persistent injection of attacker-controlled content into Agent memory **Risk Level**: Medium ### Vulnerable Code ```python # auto_log_skill.py:95-124 log_path = self.get_today_log_path() if not log_path.exists(): self.create_daily_log() try: with open(log_path, 'r', encoding='utf-8') as f: content = f.read() section_marker = f"## {section}" section_pos = content.find(section_marker) timestamp = datetime.now().strftime('%H:%M') if section_pos == -1: # Section not found — append at end new_content = f"\n### {section} ({timestamp})\n- {event}\n" else: new_content = f"\n- {timestamp} {event}" next_section_pos = content.find("\n## ", section_pos + 1) if next_section_pos == -1: next_section_pos = len(content) insert_pos = content.find("\n", section_pos) while insert_pos < next_section_pos and content[insert_pos:insert_pos + 3] == "\n- ": insert_pos = content.find("\n", insert_pos + 1) content = content[:insert_pos] + new_content + content[insert_pos:] with open(log_path, 'w', encoding='utf-8') as f: f.write(content) return True with open(log_path, 'a', encoding='utf-8') as f: f.write(new_content) ``` ```python # auto_log_skill.py:135-161 try: with open(log_path, 'r', encoding='utf-8') as f: content = f.read() section_marker = "## ✅ Tasks" section_pos = content.find(section_marker) if section_pos == -1: new_line = f"\n| {task} | {status} | {result} |\n" content = content.rstrip() + f"\n\n## ✅ Tasks\n| Task | Status | Result |\n|------|--------|--------|\n{new_line}\n" else: table_end = content.find("\n\n", section_pos) if table_end == -1: table_end = len(content) ...[truncated 2902 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat every value supplied to logging APIs as untrusted data. 2. Reject or normalize control characters and line breaks when entries are intended to occupy a single Markdown line or table cell. 3. Escape Markdown structural characters, especially pipes in table cells and heading/list syntax at the beginning of lines. 4. Validate `section` against a fixed allowlist rather than allowing arbitrary headings. 5. Apply reasonable maximum lengths to all fields. 6. Prefer a structured format such as JSON with separate fields for content, timestamp, source, and trust level. 7. If Markdown output is required, render it from structured records rather than modifying Markdown through string concatenation. 8. Mark stored content explicitly as untrusted historical data. 9. Ensure downstream Agent prompts state that log contents must never be interpreted as executable instructions. 10. Add tests containing embedded newlines, headings, Markdown table separators, comments, and prompt-injection text. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
auto_log_skill.py:217
Finding
Predictable Log Files Follow Symbolic Links During Reads and Writes<![CDATA[ ## Vulnerability Details **File Location**: `auto_log_skill.py:43-46`, `auto_log_skill.py:99-124`, `auto_log_skill.py:135-161`, `auto_log_skill.py:175-201`, and `auto_log_skill.py:217-229` **Vulnerability Type**: Symbolic-link file access in a configurable storage directory **Risk Level**: Low ### Vulnerable Code ```python # auto_log_skill.py:43-46 def get_today_log_path(self) -> Path: """Return the file path for today's log.""" today = datetime.now().strftime("%Y-%m-%d") return self.memory_dir / f"{today}.md" ``` ```python # auto_log_skill.py:217-229 log_path = self.get_today_log_path() if not log_path.exists(): return "📝 No log created for today yet" try: with open(log_path, 'r', encoding='utf-8') as f: content = f.read() summary = content[:500] if len(content) > 500: summary += "\n... (see full log for more)" return summary ``` Representative write operation: ```python # auto_log_skill.py:153-161 new_line = f"| {task} | {status} | {result} |\n" content = content[:table_end] + new_line + content[table_end:] with open(log_path, 'w', encoding='utf-8') as f: f.write(content) return True ``` ### Technical Analysis The daily filename is predictable because it is derived solely from the current date. The code uses ordinary Python `open()` calls, which follow symbolic links by default. It does not use `lstat()`, no-follow file-opening flags, or resolved-path validation before reading or rewriting the file. If the configured `memory_dir` is writable by another local user or process, that party can create the expected `YYYY-MM-DD.md` entry as a symbolic link to another file accessible to the Skill's process. The summary operation can then read the linked target, while event, task, and todo operations can modify or corrupt it. The default directory is user-scoped, which reduces practical likelihood. The issue becomes exploitable when users configure a shared, group-writable, or otherwise insuf ...[truncated 1156 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require `memory_dir` to be owned by the executing user and deny group or world write access. 2. Validate that the resolved log path remains strictly beneath the resolved memory directory. 3. Inspect existing entries with `lstat()` and reject symbolic links and non-regular files. 4. Where supported, open files with no-follow semantics such as `O_NOFOLLOW`. 5. Perform writes through a securely created temporary file in the same trusted directory, then atomically replace the destination. 6. Set restrictive file and directory permissions when creating storage. 7. Revalidate the file immediately before opening it to reduce time-of-check/time-of-use races. 8. Document that shared or attacker-writable memory directories are unsupported. 9. Add tests covering symbolic links, hard links, non-regular files, and concurrent path replacement. 10. Call `truncate()` after in-place rewrites such as `add_todo()`, or replace the file atomically, to prevent stale trailing data. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (4)

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The README explicitly advertises automatic activity logging and daily file creation, but it does not warn users that agent actions, task details, and other potentially sensitive operational data will be persisted to disk. In an agent environment, this can lead to unintentional storage of secrets, internal prompts, API-related details, or personal data in predictable locations, increasing exposure through local compromise, backups, sync tools, or accidental sharing.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explicitly states it will 'automatically record' agent activity and lists file_write as a required tool, but the description does not clearly warn users that it will persistently append data to daily log files. This can lead to unintentional storage of sensitive prompts, task data, or secrets in memory files, especially when used in agent environments where activity may include confidential information.

Missing User Warnings

Low
Confidence
93% confidence
Finding
The README prominently describes automatic creation and recording of logs, events, tasks, and todos, but does not clearly warn users that these operations persist data to files under a configured directory. In an agent skill context, silent or insufficiently disclosed persistence can cause unintentional retention of sensitive operational data, conversation-derived content, or task metadata.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The generated log template always inserts "Timezone: UTC+8", which imposes a specific locale setting in natural-language output. The file does not offer user opt-in, configuration, or any documented region-specific justification for this constraint.

Static analysis

No suspicious patterns detected.