T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/safe-writer.py:141
- Finding
- Workspace Path Traversal Through Unsanitized Task and Step Identifiers<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/safe-writer.py:141-143` - `scripts/task-memory-manager.py:61-76` - `scripts/task-memory-manager.py:107-108` - `scripts/task-memory-manager.py:132-133` - `scripts/task-memory-manager.py:215-216` - `scripts/safe-writer-ps1.txt:144-150` **Vulnerability Type**: Path traversal and insufficient path validation **Risk Level**: High ### Vulnerable Code From `scripts/safe-writer.py:141-143`: ```python task_output_dir = OUTPUT_DIR / task_id if not task_output_dir.exists(): print(f"⚠️ 任务目录不存在: {task_id}") ``` The resulting path is subsequently used to construct the metadata file: ```python meta_file = task_output_dir / ".task-meta.json" ``` From `scripts/task-memory-manager.py:61-76`: ```python def init_task(self, task_id, steps, description=""): task_dir = self.output_dir / task_id if not task_dir.exists(): print(f"⚠️ 任务目录不存在: {task_id}") return False meta_file = task_dir / ".task-meta.json" if meta_file.exists(): print(f"⚠️ 元数据已存在: {task_id}") return False for step in steps: step_dir = task_dir / step.strip() step_dir.mkdir(exist_ok=True) ``` From `scripts/task-memory-manager.py:107-108`: ```python def update_task(self, task_id, **kwargs): meta_file = self.output_dir / task_id / ".task-meta.json" ``` From `scripts/task-memory-manager.py:132-133`: ```python def add_memory_point(self, task_id, step, memory_type, summary, files=None): meta_file = self.output_dir / task_id / ".task-meta.json" ``` From `scripts/task-memory-manager.py:215-216`: ```python for task_id in task_ids: meta_file = self.output_dir / task_id / ".task-meta.json" ``` From `scripts/safe-writer-ps1.txt:144-150`: ```powershell $taskOutputDir = Join-Path $OutputDir $TaskId if (-not (Test-Path $taskOutputDir)) { Write-Host "[WARN] Task directory not found: $TaskId" return $false } $metaFile = Join-Path $taskOutputD ...[truncated 2607 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Define a strict identifier format for task and step names. For example, allow only letters, digits, underscores, and hyphens: ```python import re SAFE_COMPONENT = re.compile(r"^[A-Za-z0-9_-]+$") def validate_component(value, field_name): if not value or not SAFE_COMPONENT.fullmatch(value): raise ValueError(f"Invalid {field_name}") return value ``` 2. Resolve every derived path and confirm that it remains under the trusted base: ```python def safe_child(base: Path, component: str) -> Path: validate_component(component, "path component") resolved_base = base.resolve() candidate = (resolved_base / component).resolve() try: candidate.relative_to(resolved_base) except ValueError: raise ValueError("Path escapes the permitted workspace") return candidate ``` 3. Apply containment validation separately to: - Task identifiers - Step directory names - Metadata read paths - Metadata write paths 4. Reject absolute paths, drive-qualified paths, `.` and `..`, path separators, null bytes, and alternate separator forms before filesystem access. 5. Account for symbolic-link traversal. Validate the resolved parent directory immediately before reading, creating, or replacing the target. 6. Implement equivalent canonicalization in PowerShell: - Obtain the fully resolved candidate path. - Obtain the fully resolved output root. - Verify that the candidate is a descendant of the output root using a separator-aware comparison. - Reject the operation if containment cannot be established. 7. Add automated tests covering Unix and Windows traversal forms, absolute paths, drive prefixes, UNC paths, mixed separators, and symbolic-link escapes. ]]>
