Private
Public Access
1
0

重构:文件系统模块化架构,优化应用启动流程

This commit is contained in:
2026-01-28 00:28:54 +08:00
parent 4a9b25a505
commit 8c577f70e7
123 changed files with 32030 additions and 967 deletions

View File

@@ -0,0 +1,197 @@
package filesystem
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
// PathValidator 路径验证器接口
// 提供统一的路径安全检查,避免重复代码
type PathValidator interface {
// Validate 验证路径并返回详细的错误信息
Validate(path string) *ValidationError
// IsSafe 快速检查路径是否安全
IsSafe(path string) bool
// IsSensitive 检查路径是否为敏感路径
IsSensitive(path string) bool
}
// ValidationError 验证错误
type ValidationError struct {
Path string
Reason string
IsError bool // true=禁止访问, false=敏感路径
}
func (e *ValidationError) Error() string {
if e.IsError {
return fmt.Sprintf("路径验证失败: %s - %s", e.Path, e.Reason)
}
return fmt.Sprintf("敏感路径警告: %s - %s", e.Path, e.Reason)
}
// DefaultPathValidator 默认路径验证器实现
type DefaultPathValidator struct {
config *Config
}
// NewPathValidator 创建新的路径验证器
func NewPathValidator(config *Config) PathValidator {
return &DefaultPathValidator{
config: config,
}
}
// Validate 验证路径
func (v *DefaultPathValidator) Validate(path string) *ValidationError {
// 清理路径
cleanPath := filepath.Clean(path)
// 1. 检查路径遍历攻击
if strings.Contains(cleanPath, PathTraversalPattern) {
return &ValidationError{
Path: path,
Reason: "检测到路径遍历尝试",
IsError: true,
}
}
// 2. 检查符号链接
if !v.config.Security.PathValidation.AllowSymlinks {
if fi, err := os.Lstat(path); err == nil && fi.Mode()&os.ModeSymlink != 0 {
return &ValidationError{
Path: path,
Reason: "不允许访问符号链接",
IsError: true,
}
}
}
// 3. 检查UNC路径Windows
if runtime.GOOS == "windows" && !v.config.Security.PathValidation.AllowUNCPaths {
if strings.HasPrefix(cleanPath, `\\`) {
return &ValidationError{
Path: path,
Reason: "不允许访问UNC网络路径",
IsError: true,
}
}
}
// 4. Windows特定检查
if runtime.GOOS == "windows" && v.config.Security.PathValidation.CheckWindowsSystemPaths {
if err := v.checkWindowsSystemPaths(cleanPath); err != nil {
return err
}
}
// 5. 检查敏感路径
if v.isSensitivePath(cleanPath) {
return &ValidationError{
Path: path,
Reason: "访问敏感路径",
IsError: false, // 警告而非错误
}
}
return nil
}
// IsSafe 快速检查路径是否安全
func (v *DefaultPathValidator) IsSafe(path string) bool {
err := v.Validate(path)
return err == nil || !err.IsError
}
// IsSensitive 检查路径是否为敏感路径
func (v *DefaultPathValidator) IsSensitive(path string) bool {
cleanPath := filepath.Clean(path)
return v.isSensitivePath(cleanPath)
}
// checkWindowsSystemPaths 检查Windows系统路径
func (v *DefaultPathValidator) checkWindowsSystemPaths(path string) *ValidationError {
lowerPath := strings.ToLower(path)
// 检查盘符
if len(lowerPath) >= 3 && lowerPath[1] == ':' {
driveLetter := lowerPath[0:1]
// 检查系统关键目录
forbiddenDirs := []string{
driveLetter + ":\\windows",
driveLetter + ":\\program files",
driveLetter + ":\\program files (x86)",
driveLetter + ":\\program files (arm)",
driveLetter + ":\\programdata",
driveLetter + ":\\system volume information",
driveLetter + ":\\recovery",
driveLetter + ":\\boot",
}
for _, fb := range forbiddenDirs {
if strings.HasPrefix(lowerPath, fb) {
return &ValidationError{
Path: path,
Reason: fmt.Sprintf("禁止访问系统目录: %s", fb),
IsError: true,
}
}
}
// 检查用户配置目录(可能包含敏感信息)
forbiddenPaths := []string{
"\\.ssh\\",
"\\.gnupg\\",
"\\.config\\",
"\\appdata\\roaming\\mozilla\\",
"\\appdata\\roaming\\google\\chrome\\",
"\\appdata\\local\\google\\user data\\",
}
for _, fp := range forbiddenPaths {
if strings.Contains(lowerPath, fp) {
return &ValidationError{
Path: path,
Reason: "禁止访问敏感配置目录",
IsError: true,
}
}
}
}
return nil
}
// isSensitivePath 检查是否为敏感路径
func (v *DefaultPathValidator) isSensitivePath(path string) bool {
lowerPath := strings.ToLower(filepath.Clean(path))
// 检查配置的敏感路径列表
for _, sp := range v.config.Security.PathValidation.SensitivePaths {
if strings.Contains(lowerPath, strings.ToLower(sp)) {
return true
}
}
return false
}
// isSafePath 兼容函数:保持向后兼容
// 使用默认配置的路径验证器
func isSafePath(path string) bool {
validator := NewPathValidator(DefaultConfig())
return validator.IsSafe(path)
}
// isSensitivePath 兼容函数:保持向后兼容
// 使用默认配置检查敏感路径
func isSensitivePath(path string) bool {
validator := NewPathValidator(DefaultConfig())
return validator.IsSensitive(path)
}