Skip to main content
Glama
__init__.py7.38 kB
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 安全验证模块 提供路径验证、敏感信息检测、文件类型验证等安全功能 """ import os import re from typing import List, Dict, Any, Optional, Set from pathlib import Path import logging # 敏感信息模式 SENSITIVE_PATTERNS = { 'password': re.compile(r'password\s*[:=]\s*["\']?([^"\']+)["\']?', re.IGNORECASE), 'api_key': re.compile(r'api[_-]?key\s*[:=]\s*["\']?([^"\']+)["\']?', re.IGNORECASE), 'token': re.compile(r'token\s*[:=]\s*["\']?([^"\']+)["\']?', re.IGNORECASE), 'secret': re.compile(r'secret\s*[:=]\s*["\']?([^"\']+)["\']?', re.IGNORECASE), } # 危险文件扩展名 DANGEROUS_EXTENSIONS = { '.exe', '.bat', '.cmd', '.com', '.scr', '.pif', '.vbs', '.js', '.jar', '.app', '.deb', '.rpm', '.dmg', '.pkg', '.msi', '.dll', '.so', '.dylib' } class SecurityValidator: """安全验证器""" def __init__(self, config: Optional[Dict[str, Any]] = None): self.config = config or {} self.logger = logging.getLogger(__name__) self.allowed_paths = set(self.config.get('allowed_paths', [])) self.exclude_dirs = set(self.config.get('exclude_dirs', ['.git', '__pycache__', 'node_modules'])) def validate_path(self, path: str) -> Dict[str, Any]: """ 验证路径安全性 Args: path: 要验证的路径 Returns: 包含验证结果的字典 """ try: path_obj = Path(path).resolve() # 检查路径是否存在 if not path_obj.exists(): return { 'valid': False, 'error': f'路径不存在: {path}', 'risk_level': 'high' } # 检查路径是否在允许范围内 if self.allowed_paths and not any( str(path_obj).startswith(allowed) for allowed in self.allowed_paths ): return { 'valid': False, 'error': f'路径不在允许范围内: {path}', 'risk_level': 'high' } # 检查是否为符号链接攻击 if path_obj.is_symlink(): return { 'valid': False, 'error': f'检测到符号链接,存在安全风险: {path}', 'risk_level': 'medium' } # 检查权限 if not os.access(path_obj, os.R_OK): return { 'valid': False, 'error': f'路径无读取权限: {path}', 'risk_level': 'low' } return { 'valid': True, 'path': str(path_obj), 'risk_level': 'low' } except Exception as e: return { 'valid': False, 'error': f'路径验证异常: {str(e)}', 'risk_level': 'high' } def scan_file_content(self, content: str, file_path: str) -> List[Dict[str, Any]]: """ 扫描文件内容中的敏感信息 Args: content: 文件内容 file_path: 文件路径 Returns: 发现的敏感信息列表 """ findings = [] for pattern_name, pattern in SENSITIVE_PATTERNS.items(): matches = pattern.finditer(content) for match in matches: # 检查是否为测试数据或示例 matched_value = match.group(1) if self._is_test_data(matched_value): continue findings.append({ 'type': pattern_name, 'line': content[:match.start()].count('\n') + 1, 'match': match.group(0), 'file': file_path, 'severity': 'high' if pattern_name in ['password', 'api_key'] else 'medium' }) return findings def _is_test_data(self, value: str) -> bool: """检查是否为测试数据""" test_indicators = ['test', 'demo', 'example', 'sample', 'fake', 'mock', 'placeholder'] value_lower = value.lower() return any(indicator in value_lower for indicator in test_indicators) def validate_file_type(self, file_path: str) -> Dict[str, Any]: """ 验证文件类型安全性 Args: file_path: 文件路径 Returns: 验证结果 """ path_obj = Path(file_path) extension = path_obj.suffix.lower() if extension in DANGEROUS_EXTENSIONS: return { 'safe': False, 'extension': extension, 'risk_level': 'high', 'message': f'危险文件类型: {extension}' } return { 'safe': True, 'extension': extension, 'risk_level': 'low' } def validate_directory_structure(self, directory: str) -> Dict[str, Any]: """ 验证目录结构安全性 Args: directory: 目录路径 Returns: 验证结果 """ try: path_obj = Path(directory) # 检查目录是否在排除列表中 dir_name = path_obj.name if dir_name in self.exclude_dirs: return { 'safe': False, 'reason': f'目录在排除列表中: {dir_name}', 'risk_level': 'low' } # 检查目录深度(防止路径遍历攻击) relative_parts = path_obj.relative_to(Path.cwd()).parts if len(relative_parts) > 20: # 设置最大深度 return { 'safe': False, 'reason': f'目录过深,可能存在路径遍历风险: {len(relative_parts)}层', 'risk_level': 'medium' } return { 'safe': True, 'depth': len(relative_parts), 'risk_level': 'low' } except Exception as e: return { 'safe': False, 'reason': f'目录结构验证异常: {str(e)}', 'risk_level': 'high' } def get_security_validator(config: Optional[Dict[str, Any]] = None) -> SecurityValidator: """获取安全验证器实例""" return SecurityValidator(config) # 便捷函数 def validate_path_safety(path: str, config: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: """验证路径安全性的便捷函数""" validator = get_security_validator(config) return validator.validate_path(path) def scan_content_security(content: str, file_path: str, config: Optional[Dict[str, Any]] = None) -> List[Dict[str, Any]]: """扫描内容安全性的便捷函数""" validator = get_security_validator(config) return validator.scan_file_content(content, file_path)

Latest Blog Posts

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/kscz0000/Zhiwen-Assistant-MCP'

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