Private
Public Access
1
0
Files
u-desk/internal/filesystem/path_validator.go
绝尘 a5d30684ed 重构:文件系统模块化架构,增强 Markdown 渲染
- 拆分 FileSystem.vue 为模块化组件架构
- 新增 Markdown Mermaid 图表渲染支持
- 新增 180+ 编程语言代码高亮
- 修复编辑/预览模式切换渲染问题
- 优化亮色/暗色模式主题适配
- 新增 TypeScript 类型定义
2026-02-04 03:32:46 +08:00

196 lines
4.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 + ":\\system volume information",
driveLetter + ":\\boot",
}
for _, fb := range forbiddenDirs {
if strings.HasPrefix(lowerPath, fb) {
return &ValidationError{
Path: path,
Reason: "禁止访问系统关键目录",
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)
}