T09 · Insecure Skill Coding Practices
- Location
scripts/guandata.py:254- Finding
Cache Path Traversal Through Unvalidated Task and Dataset Identifiers
- Content
View full analysis
str: if cls._task_id: return os.path.join( cls.SKILL_ROOT, '.cache', 'tasks', cls._task_id, subdir, ) return os.path.join(cls.SKILL_ROOT, '.cache', subdir) ``` The resulting path is used directly for file creation: ```python def _save_to_cache(self, data: Any, prefix: str = "data") -> str: self._ensure_data_cache_dir() ts = datetime.now().strftime("%Y%m%d_%H%M%S_%f")[:-3] filename = f"{prefix}_{ts}.json" path = os.path.join(self.DATA_CACHE_DIR, filename) with open(path, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) return path ``` Dataset identifiers are also used directly as filenames: ```python path = os.path.join(self.COLUMNS_CACHE_DIR, f"{ds_id}.json") ``` The task value is accepted without validation: ```python parser.add_argument( '--task', help='Task name used to isolate caches for different tasks', ) if args.task: GuandataClient.set_task(args.task) ``` ### Technical Analysis The `--task` argument is inserted directly into a filesystem path. The implementation does not reject absolute paths, path separators, or parent-directory components such as `..`. It also does not resolve the resulting path and verify that it remains under the intended `.cache/tasks` directory. Consequently, a task identifier such as `../../../../target` can cause cache files containing BI query results to be written outside the Skill cache. An absolute path can similarly replace the intended path prefix under standard `os.path.join()` behav ...[truncated 1580 chars]- Remediation
View remediation
