Skip to main content
Glama
security.py4.4 kB
""" 安全验证模块 处理文件路径验证、权限检查等安全相关功能 """ import os import logging from pathlib import Path from typing import List, Optional from .config import ConfigManager class SecurityValidator: """安全验证器""" def __init__(self, config_manager: ConfigManager): self.config_manager = config_manager self.allowed_paths = config_manager.get_allowed_paths() self.forbidden_extensions = config_manager.get('security.forbidden_extensions', []) def validate_file_path(self, file_path: str) -> bool: """验证文件路径是否安全""" try: # 解析路径 path = Path(file_path).expanduser().resolve() # 检查路径是否存在 if not path.exists() and not self._is_creation_allowed(path): logging.warning(f"文件路径不存在且不允许创建: {path}") return False # 检查是否在允许的路径内 if not self._is_path_allowed(path): logging.warning(f"文件路径不在允许范围内: {path}") return False # 检查文件扩展名 if not self._is_extension_allowed(path): logging.warning(f"文件扩展名不被允许: {path.suffix}") return False return True except Exception as e: logging.error(f"路径验证错误: {e}") return False def _is_creation_allowed(self, path: Path) -> bool: """检查是否允许创建文件""" # 检查父目录是否在允许的路径内 parent = path.parent return self._is_path_allowed(parent) def _is_path_allowed(self, path: Path) -> bool: """检查路径是否在允许的范围内""" path_str = str(path) for allowed_path in self.allowed_paths: try: # 检查是否为允许路径的子路径 if path_str.startswith(allowed_path): return True # 检查是否为完全匹配 if str(Path(allowed_path).resolve()) == path_str: return True except Exception: continue return False def _is_extension_allowed(self, path: Path) -> bool: """检查文件扩展名是否允许""" extension = path.suffix.lower() # 检查是否为禁止的扩展名 if extension in self.forbidden_extensions: return False # 检查是否为支持的Excel格式 supported_formats = self.config_manager.get_supported_formats() if extension in supported_formats: return True # 对于其他扩展名,默认不允许 return False def sanitize_path(self, file_path: str) -> Optional[str]: """清理和标准化文件路径""" try: path = Path(file_path).expanduser().resolve() return str(path) except Exception as e: logging.error(f"路径清理错误: {e}") return None def check_file_size(self, file_path: str) -> bool: """检查文件大小是否在限制范围内""" try: path = Path(file_path) if not path.exists(): return True # 新文件,允许创建 file_size = path.stat().st_size max_size_str = self.config_manager.get('excel.max_file_size', '100MB') max_size = self._parse_size(max_size_str) return file_size <= max_size except Exception as e: logging.error(f"文件大小检查错误: {e}") return False def _parse_size(self, size_str: str) -> int: """解析大小字符串(如 '100MB')为字节数""" size_str = size_str.strip().upper() if size_str.endswith('KB'): return int(size_str[:-2]) * 1024 elif size_str.endswith('MB'): return int(size_str[:-2]) * 1024 * 1024 elif size_str.endswith('GB'): return int(size_str[:-2]) * 1024 * 1024 * 1024 else: return int(size_str) # 假设为字节数

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/xuhongxin/excel-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server