Back to skill

Security audit

Plan Do Check Act

Security checks for vulnerabilities and agentic risk

Overview

This planning skill is mostly purpose-aligned, but its scripts can operate beyond the documented plan workspace and expose saved session/task metadata.

Review this skill before installing. Use it only in a dedicated workspace, avoid storing real session IDs or sensitive task names in shared plan files, do not pass absolute paths or parent-directory paths to its commands, and be cautious with on-start, archive, cleanup, and progress checks because they can reveal filenames or modify files beyond the stated plan scope.

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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/manage_plan.py:37
Finding

Unrestricted Path Arguments Allow Arbitrary File Overwrite and Relocation

Content
View full analysis
2 else "plan.md" archive_dir = "archive" if "--dir" in sys.argv: idx = sys.argv.index("--dir") archive_dir = sys.argv[idx + 1] archive_plan(output_path, archive_ ...[truncated 2662 chars]
Remediation
View remediation
/archive`; do not accept an unrestricted `--dir` argument. 4. Reject symbolic links for files and relevant parent directories, or securely resolve them and revalidate the resolved target against the workspace root. 5. Use exclusive creation mode (`'x'`) for new plans. If replacement is required, demand explicit confirmation or a dedicated `--force` option. 6. Before archive or cleanup operations, verify that each target is a regular file under the approved directory. 7. Apply the same centralized path-validation function to `create`, `update`, `check`, `pause`, `resume`, `archive`, `cleanup`, `list`, and `on-start`. 8. Add tests covering absolute paths, `../` traversal, symlink traversal, filenames that do not match `plan*.md`, and archive destinations outside the workspace. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/check_progress.py:39
Finding

Progress Recovery Can Recursively Inventory Files Outside the Declared Plan Scope

Content
View full analysis
list: """Get recently modified files""" recent = [] cutoff = datetime.now() - timedelta(minutes=minutes) for root, dirs, files in os.walk(workspace): # Skip common directories skip_dirs = {'node_modules', '.git', '__pycache__', 'venv', 'dist', 'build', 'archive'} dirs[:] = [d for d in dirs if d not in skip_dirs] for file in files: if file.endswith(('.skill', '.pyc', '.log')): continue filepath = os.path.join(root, file) try: mtime = datetime.fromtimestamp(os.path.getmtime(filepath)) if mtime > cutoff: rel_path = os.path.relpath(filepath, workspace) recent.append({ 'path': rel_path, 'mtime': mtime, 'age': datetime.now() - mtime }) except: pass ``` ```python git_status = get_git_status(workspace) print(f"\n💻 Git Status: {len(git_status)} changes") if git_status: for status in git_status[:5]: print(f" {status}") if len(gi ...[truncated 3071 chars]
Remediation
View remediation
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 (25)

Tainted flow: 'workspace' from input (line 166, user input) → subprocess.run (code execution)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

External input (network, user) flows to a code execution sink. This enables remote code execution or command injection.

Content

Scanner excerpt · scripts/setup.py (reported line 104)May include surrounding context.

python
return True
    
    try:
        result = subprocess.run(
            ['git', 'init'],
            cwd=workspace,
            capture_output=True,

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description emphasizes PDCA workflow automation with session binding and progress recovery, implying stateful workflow support and the ability to resume progress. The supplied code does not implement session handling, persistence, recovery, or Git-related behavior. Instead, it performs a narrow text-analysis function: scoring task complexity from keywords and printing a recommendation about whether to plan or execute. While this is adjacent to PDCA planning, it is materially narrower than the declared purpose and omits the key advertised capabilities of session binding and progress recovery.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The declared description promises PDCA workflow automation with session binding and progress recovery. The supplied code does not implement session binding, recovery, or general workflow automation. Instead, it only reads a markdown plan file, parses dependency and checklist sections, and reports prerequisite violations. While dependency checking could be a supporting feature within a PDCA workflow, the declared purpose materially overstates and misrepresents this specific code chunk’s actual functionality.

Content

No source excerpt is available for this finding.

Context Leakage

High
Category
Data Exfiltration
Confidence
98% confidence
Finding

The skill tells the agent to record the session ID directly in plan.md, and the example later uses a concrete session identifier. Persisting conversation/session identifiers in user-accessible workspace files creates context leakage and can enable cross-session correlation, privacy loss, or accidental disclosure when plans are listed or shared.

Content

Scanner excerpt · SKILL.md (reported line 65)May include surrounding context.

md
### 1. Plan
When receiving a user task, create `plan.md`:
- Break down the task into executable subtasks
- Record the session ID
- Mark priorities and dependencies

### 2. Do

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/check_progress.py (reported line 153)May include surrounding context.

python
elif progress['task_type'] == 'deploy':
        deploy_files = [f for f in recent_files 
                       if any(kw in f['path'].lower() for kw in ['config', 'docker', 'deploy', '.env', 'log'])]
        if deploy_files:
            progress['likely_started'] = True
            progress['evidence'].append(f"Deploy related: {deploy_files[0]['path']}")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill describes file reads/writes and shell execution but does not declare any tool scope restrictions such as allowed tools or permissions. In an agent environment, this increases the chance of unintended filesystem or command execution beyond the narrow PDCA purpose, especially because the document includes commands for setup, git operations, and cleanup.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The keyword list includes generic terms like 'plan', 'checklist', and 'todo', which are common in benign conversation and can cause over-triggering. That raises the risk that the skill reads, creates, or updates persistent planning data when the user did not intend to invoke the workflow.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill explicitly instructs the agent to display uncompleted plans for both the current session and other sessions, including session identifiers and progress details. This is a direct cross-session data exposure risk because one user could be shown task names, status, and metadata belonging to another conversation or tenant.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The automatic trigger phrases are broad enough to match ordinary conversation such as asking about status or pending work, which can invoke plan inspection or stateful behavior without clear user authorization. In a multi-session or shared workspace context, that can cause unintended disclosure of plan contents or actions on prior state.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The workflow says that when users ask broad questions like 'What's not done?' or 'Show me the plan', the agent should automatically run plan checks and output incomplete plans, but it does not require any explicit authorization check. This can expose stored task details to whoever asks, especially if the workspace persists across sessions or identities.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/check_progress.py (reported line 16)May include surrounding context.

python
def get_git_status(workspace: str = "."):
    """Get git status"""
    try:
        result = subprocess.run(
            ['git', 'status', '--porcelain'],
            cwd=workspace,
            capture_output=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
78% confidence
Finding

The script executes a secondary Python file located relative to the current script path, which means whoever controls that file on disk controls code that will be run. In a skill/plugin context, chaining execution into another script expands the trust boundary and can become dangerous if the package contents are modified, replaced, or partially trusted by the user.

Content

Scanner excerpt · scripts/check_progress.py (reported line 265)May include surrounding context.

python
if os.path.exists(dep_script):
        import subprocess
        try:
            proc = subprocess.run(
                ['python3', dep_script, plan_path],
                capture_output=True,
                text=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

create_plan writes directly to an arbitrary caller-supplied output_path with truncation semantics and no validation or confirmation. In an agent context, if an attacker can influence arguments, this can overwrite unexpected files within the agent's permissions, causing data loss or corruption of workspace content.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The comments and surrounding logic indicate the function updates the 'Current Task' section and completion status in the plan content, but after modifying the string variable content, the function writes \n.join(lines) instead. As a result, the documented/annotated behavior contradicts what is actually persisted, because the Current Task section and COMPLETED status edits made on content may be lost.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest describes PDCA workflow automation with session binding and progress recovery, which justifies reading and updating plan files, but this file also launches a separate Python process during session start. Spawning subprocesses is a broader execution capability than is obviously required for managing markdown plans and recovering progress, especially since the manifest only mentions Git as optional and does not describe arbitrary command execution.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/manage_plan.py (reported line 391)May include surrounding context.

python
if os.path.exists(check_script):
            import subprocess
            try:
                proc = subprocess.run(
                    ['python3', check_script, workspace, first_plan['path']],
                    capture_output=True,
                    text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/setup.py (reported line 14)May include surrounding context.

python
def check_python():
    """Check Python version"""
    try:
        result = subprocess.run(['python3', '--version'], capture_output=True, text=True)
        if result.returncode == 0:
            print(f"✓ Python: {result.stdout.strip()}")
            return True

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/setup.py (reported line 28)May include surrounding context.

python
def check_git():
    """Check if Git is available"""
    try:
        result = subprocess.run(['git', '--version'], capture_output=True, text=True)
        if result.returncode == 0:
            print(f"✓ Git: {result.stdout.strip()}")
            return True

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/setup.py (reported line 104)May include surrounding context.

python
return True
    
    try:
        result = subprocess.run(
            ['git', 'init'],
            cwd=workspace,
            capture_output=True,

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The file runs git status and later executes check_deps.py through subprocess.run, but the user-facing description does not clearly disclose that external processes will be spawned. Even though these commands are read-oriented and aligned with the tool's purpose, there is no explicit notice in code comments, prompts, or printed messaging before execution.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The comment # Confidence判断 mixes English and Chinese, indicating the skill may assume a specific locale context without documenting or offering language selection. Under the language/locale policy rule, implicit locale constraints should be surfaced or made optional.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The script enumerates recently modified files and prints their relative paths, which can expose sensitive project structure, secret-bearing filenames, or activity patterns to logs or terminal captures. In a recovery/progress tool, this disclosure is part of the feature, but it still creates an information exposure risk if output is shared or collected elsewhere.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The update_plan_status function rewrites the specified plan file in place after transforming its contents. The function logs success only after the write and does not provide any pre-write notice or confirmation that the file will be modified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The pause_plan function updates status and pause history, then writes the modified content back to the same file. There is no confirmation prompt or advance disclosure that invoking pause changes the file on disk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The resume_plan function rewrites the plan file after changing status and pause history. While it prints progress afterward, it does not warn beforehand that the operation will alter the file contents.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.