T09 · Insecure Skill Coding Practices
- Location
config.py:53- Finding
Path Traversal in Local History Storage
- Content
View full analysis
str: """获取数据文件路径""" import os from datetime import datetime if not date_str: date_str = datetime.now().strftime("%Y-%m-%d") data_dir = self.data_dir if source_id: # 按热榜源分目录存储 source_dir = os.path.join(data_dir, source_id) os.makedirs(source_dir, exist_ok=True) return os.path.join(source_dir, f"{date_str}.json") else: # 主目录 os.makedirs(data_dir, exist_ok=True) return os.path.join(data_dir, f"all_{date_str}.json") ``` The resulting path is used by the following write operation: ```python def save_hot_list(self, source_id: str, data: Dict[str, Any]) -> bool: """ 保存热榜数据到文件 Args: source_id: 热榜源 ID(如 weibo, zhihu) data: 热榜数据字典 Returns: 是否保存成功 """ if not self.auto_save: return False try: # 获取今日日期的文件路径 file_path = config.get_data_path(source_id) # 构建存储结构 storage_data = { "source_id": source_id, "save_time": datetime.now().isoformat(), "update_time": data.get("update_time", ""), "total": data.get("total", 0), "data": data.get("data", []) } # 读取现有数据(如果有) existing_data = [] if os.path.exists(file_path): with open(file_path, 'r', encoding='utf-8') as f: try: existing_data = json.load(f) if not isinstance(existing_data, list): existing_data = [] except: existing_data = [] # 添加新数据到列表 ...[truncated 3565 chars]- Remediation
View remediation
str: root = Path(self.data_dir).resolve() root.mkdir(parents=True, exist_ok=True) if source_id not in HOT_SOURCES: raise ValueError("Unsupported source identifier") if not date_str: date_str = datetime.now().strftime("%Y-%m-%d") parsed_date = datetime.strptime(date_str, "%Y-%m-%d") safe_date = parsed_date.strftime("%Y-%m-%d") source_dir = (root / source_id).resolve() if source_dir.parent != root: raise ValueError("Invalid source path") source_dir.mkdir(parents=True, exist_ok=True) target = (source_dir / f"{safe_date}.json").resolve() if target.parent != source_dir: raise ValueError("Path escapes the source directory") return str(target) ``` 4. Keep directory creation out of read-only path resolution. A load operation should not mutate the filesystem. 5. Apply the same containment validation to direct path construction in `load_history()`, `get_saved_dates()`, and cleanup routines. 6. Add tests covering absolute paths, `../`, nested traversal, path separators, malformed dates, and symbolic links. 7. Run the Skill under a dedicated low-privilege account with write access only to its intended data directory. ]]>
