Back to skill

Security audit

Incident Replay

Security checks for vulnerabilities and agentic risk

Overview

This forensic skill is purpose-aligned and not malicious, but it should be reviewed because it can copy broad workspace file contents into persistent local incident data without strong secret controls or symlink containment.

Install only if you are comfortable with local forensic copies of your workspace. Before use, set a narrow WORKSPACE_ROOT, aggressively exclude secrets, credentials, logs, agent memory, and unrelated projects, avoid running it in workspaces writable by untrusted users, and review snapshot/report files before sharing or committing them.

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

T09 · Insecure Skill Coding Practices

Warning
Location
incident_capture.py:218
Finding
Plaintext Collection and Retention of Sensitive Workspace and Agent-Memory Content<![CDATA[ ## Vulnerability Details **File Location**: `incident_capture.py:218-252`, `incident_capture.py:139-145`, `config_example.json:20-38`, `config_example.py:30-42`, `config_example.py:209` **Vulnerability Type**: Plaintext sensitive-data collection and storage **Risk Level**: Medium ### Vulnerable Code Default configuration includes source code, configuration, logs, JSON data, Markdown documents, and agent-memory files without excluding common secret-bearing files: ```json "EXCLUDE_PATTERNS": [ "__pycache__/*", "*.pyc", ".git/*", "node_modules/*", "incident_data/*", "*.tmp", "*.swp" ], "INCLUDE_PATTERNS": [ "*.py", "*.md", "*.txt", "*.json", "*.jsonl", "*.yaml", "*.yml", "*.toml", "*.cfg", "*.ini", "*.log" ], "LOG_FILES": [ "*.log", "memory/*.md", "*.jsonl" ] ``` The snapshot implementation reads matching files verbatim: ```python for dirpath, dirnames, filenames in os.walk(self.root): # Skip excluded directories dirnames[:] = [ d for d in dirnames if not _matches_any(os.path.join(dirpath, d) + "/", self.exclude) ] for fname in filenames: full_path = os.path.join(dirpath, fname) rel_path = os.path.relpath(full_path, self.root) if not _matches_any(rel_path, self.include): continue if _matches_any(rel_path, self.exclude): continue try: stat = os.stat(full_path) except OSError: continue size = stat.st_size total_size += size if total_size > self.max_snapshot_size: raise RuntimeError( f"Snapshot exceeds MAX_SNAPSHOT_SIZE ({self.max_snapshot_size} bytes). " f"Adjust INCLUDE_PATTERNS or MAX_SNAPSHOT_SIZE." ) fhash = _file_hash(full_path) content = None if size <= self.max_file_size: try: with open(full_path, "r", encoding="utf-8", errors="replace") as fh: ...[truncated 2852 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make metadata-only capture the default and require explicit opt-in before storing file content. 2. Add secure default exclusions for: - `.env` and `.env.*` - Private keys and certificates - Credential and token files - Cloud-provider configuration directories - Agent memory and conversation history - Authentication cookies and session files 3. Provide an explicit allowlist of approved capture paths rather than relying primarily on extension-based matching. 4. Run secret redaction before serialization. Replace secret values with irreversible placeholders while preserving enough context for forensic analysis. 5. Ensure detection prevents storage rather than merely recording that a pattern was found. 6. Create data directories with mode `0700` and snapshot, incident, and report files with mode `0600` where supported. 7. Support encryption at rest with keys stored outside the snapshot directory. 8. Warn users when the selected configuration includes logs, memory, configuration, or other likely sensitive content. 9. Add configurable retention periods and secure deletion guidance. 10. Document that snapshot and report files must not be committed, synchronized, or shared without review. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
incident_capture.py:218
Finding
Workspace Boundary Bypass Through Symlink Following<![CDATA[ ## Vulnerability Details **File Location**: `incident_capture.py:218-252` **Vulnerability Type**: Symlink-based unauthorized file access **Risk Level**: Medium ### Vulnerable Code ```python for dirpath, dirnames, filenames in os.walk(self.root): # Skip excluded directories dirnames[:] = [ d for d in dirnames if not _matches_any(os.path.join(dirpath, d) + "/", self.exclude) ] for fname in filenames: full_path = os.path.join(dirpath, fname) rel_path = os.path.relpath(full_path, self.root) if not _matches_any(rel_path, self.include): continue if _matches_any(rel_path, self.exclude): continue try: stat = os.stat(full_path) except OSError: continue size = stat.st_size total_size += size if total_size > self.max_snapshot_size: raise RuntimeError( f"Snapshot exceeds MAX_SNAPSHOT_SIZE ({self.max_snapshot_size} bytes). " f"Adjust INCLUDE_PATTERNS or MAX_SNAPSHOT_SIZE." ) fhash = _file_hash(full_path) content = None if size <= self.max_file_size: try: with open(full_path, "r", encoding="utf-8", errors="replace") as fh: content = fh.read() except (OSError, IOError): pass files[rel_path] = FileEntry( path=rel_path, size=size, modified=stat.st_mtime, sha256=fhash, content=content, ) ``` ### Technical Analysis The implementation derives a lexical path beneath `WORKSPACE_ROOT`, but it does not resolve the path and verify that the final file remains inside that root. Both `os.stat()` and the ordinary `open()` call follow symbolic links. Consequently, a symbolic link whose directory entry is inside the workspace may point to a file anywhere else that is readable by the process. The ...[truncated 1994 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Reject symbolic links by default using `os.lstat()` or `os.path.islink()` before hashing or reading a file. 2. Resolve the workspace root and each candidate with `os.path.realpath()`, then enforce containment with `os.path.commonpath()`: ```python root_real = os.path.realpath(self.root) candidate_real = os.path.realpath(full_path) if os.path.commonpath([root_real, candidate_real]) != root_real: continue ``` 3. Do not rely on string-prefix checks, because paths such as `/workspace-other` can share a prefix with `/workspace`. 4. Where supported, open files using no-follow semantics such as `os.open()` with `O_NOFOLLOW`, then read through the returned descriptor. 5. Perform metadata checks on the opened file descriptor to reduce time-of-check/time-of-use races. 6. Verify that the opened object is a regular file before reading it. 7. Apply equivalent boundary validation to configured data, snapshot, incident, and report paths. 8. Add automated tests covering: - File symlinks to external targets - Symlink chains - Broken symlinks - Relative symlink targets - Symlink replacement races - Legitimate regular files inside the workspace ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (18)

Credential Access

High
Category
Privilege Escalation
Content
deletions += 1
            if ctype == "modified" and any(
                p in path.lower()
                for p in ["config", ".cfg", ".ini", ".yaml", ".yml", ".env"]
            ):
                config_changes += 1
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill describes functionality that reads and writes workspace data, including snapshots and reports, but does not declare any explicit tool scope or permissions boundaries. This increases the risk of overbroad file access because operators and automated systems cannot easily determine what filesystem capabilities the skill requires or constrain it to least privilege.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill prominently advertises capturing workspace state, including file content, but does not place an up-front warning that snapshots may collect secrets, credentials, tokens, or other sensitive material from the monitored workspace. In a forensics context this is particularly dangerous because users may snapshot broad directories and then persist or share incident artifacts that contain confidential data.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The trigger system is described in broad terms such as log patterns, file changes, and content scans without clear constraints, allowlists, or safe defaults. In a forensic tool that scans workspace contents and logs, underspecified trigger logic can lead to overcollection of sensitive data, noisy or misleading incident classification, and unsafe monitoring scope if users enable broad patterns without understanding the privacy impact.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
The snapshot routine reads and stores full contents of every included file up to MAX_FILE_SIZE, then persists them to JSON snapshots on disk. In a forensic tool operating over an entire workspace, this can capture credentials, proprietary code, personal data, tokens, and incident artifacts far beyond metadata-only state capture, creating a high-risk local data hoard and secondary disclosure surface.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The tool silently captures file contents from the workspace and saves them without any user-facing notice that sensitive data may be collected and retained. In incident-response scenarios, operators may point the tool at production workspaces containing secrets and regulated data, so lack of transparency materially raises the risk of accidental overcollection and unsafe retention.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
Trigger output includes matched log excerpts and file-pattern evidence, which can surface sensitive strings directly in console output or JSON results. That creates a disclosure channel to terminals, CI logs, chat transcripts, or downstream systems consuming the output, especially in a forensic workflow where logs often contain tokens, PII, or internal identifiers.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
The trigger engine scans arbitrary file contents with configured regex patterns, turning a post-mortem state tool into a general content inspection mechanism. In this skill context, broad workspace scanning increases the chance of processing sensitive materials unrelated to the incident and exposing their existence or matching text through findings.

Description-Behavior Mismatch

Medium
Confidence
90% confidence
Finding
The module description and implementation show that the skill does more than transient post-mortem analysis: it maintains a persistent incident store containing timelines, triggers, decisions, file changes, and notes. In a forensics context, those artifacts can contain sensitive operational data, so expanding from analysis into durable storage increases privacy and data-exposure risk if users do not explicitly expect or consent to retention.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The create_incident flow serializes and saves incident data without any explicit warning that analysis results will be retained on disk. Because the collected data can include log-derived decision points and file-change context from failure investigations, users may unknowingly persist sensitive material, creating confidentiality and compliance risk.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The code unconditionally writes incident records to disk via _save_incident(), persisting potentially sensitive forensic data such as decision text, triggers, and file-change details. In this skill context, stored post-mortem artifacts may include secrets, internal paths, or operational metadata, making silent persistence more dangerous than ordinary application logging.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The tool can persist full incident reports to disk, and those reports may contain sensitive forensic data such as decision chains, file diffs, triggers, and notes. In an incident-forensics context this materially increases exposure risk because users may unintentionally write confidential operational or security data to an insecure location without explicit warning or confirmation.

Scope Creep

Low
Category
Excessive Agency
Content
**USE AT YOUR OWN RISK.**

- The author(s) are NOT liable for any damages, losses, or consequences arising from 
  the use or misuse of this software — including but not limited to financial loss, 
  data loss, security breaches, business interruption, or any indirect/consequential damages.
- This software does NOT constitute financial, legal, trading, or professional advice.
- Users are solely responsible for evaluating whether this software is suitable for
Confidence
70% confidence
Finding
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Scope Creep

Low
Category
Excessive Agency
Content
**USE AT YOUR OWN RISK.**

- The author(s) are NOT liable for any damages, losses, or consequences arising from 
  the use or misuse of this software — including but not limited to financial loss, 
  data loss, security breaches, business interruption, or any indirect/consequential damages.
- This software does NOT constitute financial, legal, trading, or professional advice.
- Users are solely responsible for evaluating whether this software is suitable for
Confidence
70% confidence
Finding
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Intent-Code Divergence

Low
Confidence
78% confidence
Finding
The documentation states that the software 'does not transmit data externally unless explicitly configured by the user,' which implies the existence of some external transmission behavior. However, the rest of the manifest consistently describes a local, stdlib-only forensic tool focused on snapshots, timelines, and local report generation, with no documented network/export feature. This is an intent-level contradiction in the documentation rather than a mere omission.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Content
def _get(cfg: Any, name: str, default: Any = None) -> Any:
    if isinstance(cfg, dict):
        return cfg.get(name, default)
    return getattr(cfg, name, default)


class ReportGenerator:
Confidence
50% confidence
Finding
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Content
def _get(cfg: Any, name: str, default: Any = None) -> Any:
    if isinstance(cfg, dict):
        return cfg.get(name, default)
    return getattr(cfg, name, default)


class ReportGenerator:
Confidence
50% confidence
Finding
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Content
def _get(cfg: Any, name: str, default: Any = None) -> Any:
    if isinstance(cfg, dict):
        return cfg.get(name, default)
    return getattr(cfg, name, default)


class ReportGenerator:
Confidence
50% confidence
Finding
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Static analysis

No suspicious patterns detected.