T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/skill_cache_cli.py:168- Finding
Unrestricted Path Traversal in the Bundled Cache CLI
- Content
View full analysis
Path: """Get the shared file path.""" shared_path = self.config.cache_root / ".shared" shared_path.mkdir(parents=True, exist_ok=True) return shared_path / filename ``` ```python def _get_skill_path(self, skill_name: str, subdir: str = "data") -> Path: """Get a Skill directory path.""" if subdir not in self.SUBDIR_TYPES: raise ValueError( f"Unknown subdirectory type: {subdir}. " f"Available: {list(self.SUBDIR_TYPES.keys())}" ) skill_path = self.config.cache_root / skill_name / subdir skill_path.mkdir(parents=True, exist_ok=True) return skill_path def _get_file_path( self, skill_name: str, filename: str, subdir: str = "data" ) -> Path: """Get a complete file path.""" return self._get_skill_path(skill_name, subdir) / filename ``` ```python # shared read shared_read = shared_subparsers.add_parser("read", help="Read shared file") shared_read.add_argument("file", help="File name") # shared write shared_write = shared_subparsers.add_parser("write", help="Write shared file") shared_write.add_argument("file", help="File name") shared_write.add_argument("--content", "-c", required=True, help="File content") # shared delete shared_delete = shared_subparsers.add_parser("delete", help="Delete shared file") shared_delete.add_argument("file", help="File name") ``` ### Technical Analysis The CLI directly joins user-controlled `filename` and `skill_name` values to trusted cache directories. It does not reject absolute paths, `..` components, or symlink destinations, and it does not verify that the resolved result remains beneath the intended c ...[truncated 1529 chars]- Remediation
View remediation
Path: candidate_input = Path(user_path) if candidate_input.is_absolute() or ".." in candidate_input.parts: raise ValueError("Unsafe path") resolved_root = root.resolve(strict=True) candidate = (resolved_root / candidate_input).resolve(strict=False) candidate.relative_to(resolved_root) return candidate ``` 3. Restrict shared filenames to a narrow allowlist, such as `mt_auth_tokens.json`, where possible. 4. Validate `skill_name` against a conservative identifier pattern rather than accepting path syntax. 5. Reject symlinks for sensitive files and parent directories, or use descriptor-relative APIs with no-follow protections. 6. Apply the validation consistently to read, write, append, delete, JSON, and line-oriented operations. 7. Add regression tests for absolute paths, nested traversal, encoded traversal, and symlink escapes. ]]>
