-
-
Notifications
You must be signed in to change notification settings - Fork 51
fix: 修改日志export指令的临时文件位置及上传方式 #1546
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
22c4df0
ec5a6be
29b7655
2d56c2a
51b5036
d6d476a
e3822ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -955,14 +955,26 @@ func LogEditByID(ctx *MsgContext, groupID, logName, content string, messageID in | |||||
| } | ||||||
|
|
||||||
| func GetLogTxt(ctx *MsgContext, groupID string, logName string, fileNamePrefix string) (string, error) { | ||||||
| // 创建临时文件 | ||||||
| tempLog, err := os.CreateTemp("", fmt.Sprintf( | ||||||
| // 创建临时文件,优先使用海豹数据目录 | ||||||
| dice := ctx.Dice | ||||||
| tempDir := filepath.Join(dice.BaseConfig.DataDir, "temp") | ||||||
| _ = os.MkdirAll(tempDir, 0o755) | ||||||
|
|
||||||
| tempLog, err := os.CreateTemp(tempDir, fmt.Sprintf( | ||||||
| "%s(*).txt", | ||||||
| utils.FilenameClean(fileNamePrefix), | ||||||
| )) | ||||||
| if err != nil { | ||||||
| return "", errors.New("log导出出现未知错误") | ||||||
|
||||||
| return "", errors.New("log导出出现未知错误") | |
| return "", fmt.Errorf("创建临时文件失败: %w", err) |
Copilot
AI
Dec 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent error handling: When os.Chmod fails, the error message is generic "设置临时文件权限失败" without preserving the underlying error context. However, other error paths in this function (lines 1040, 1051) properly wrap errors with fmt.Errorf and %w. For consistency and better debugging, wrap the error: return "", fmt.Errorf("设置临时文件权限失败: %w", err1).
| return "", errors.New("设置临时文件权限失败") | |
| return "", fmt.Errorf("设置临时文件权限失败: %w", err1) |
Copilot
AI
Dec 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potentially excessive file permissions: Setting file permissions to 0o644 (readable by all users) may be more permissive than necessary. Temporary log files could contain sensitive information like user IDs, nicknames, and message content. Consider using 0o600 (readable only by owner) unless group/other read access is specifically required for the NapCat integration. If broader permissions are necessary, document the security rationale in a comment.
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -34,13 +34,25 @@ func GetLogTxtAndParquetFile(env UploadEnv) (*os.File, *bytes.Buffer, error) { | |||||||||
| ), | ||||||||||
| )) | ||||||||||
| buf := new(bytes.Buffer) | ||||||||||
| tempLog, err := os.CreateTemp("", fmt.Sprintf( | ||||||||||
|
|
||||||||||
| // 尝试创建临时文件,优先使用海豹数据目录 | ||||||||||
| tempDir := filepath.Join(env.Dir, "temp") | ||||||||||
| _ = os.MkdirAll(tempDir, 0o755) | ||||||||||
|
||||||||||
| _ = os.MkdirAll(tempDir, 0o755) | |
| if err := os.MkdirAll(tempDir, 0o755); err != nil { | |
| return nil, nil, fmt.Errorf("创建临时目录失败: %w", err) | |
| } |
Copilot
AI
Dec 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent error handling: When os.Chmod fails, the error message is wrapped as "设置临时文件权限失败: %w" preserving the original error context. However, when os.CreateTemp fails, the generic error message "log导出出现未知错误" is returned, losing the original error context. For better debugging, preserve the original error with fmt.Errorf("创建临时文件失败: %w", err).
| return nil, nil, errors.New("log导出出现未知错误") | |
| return nil, nil, fmt.Errorf("创建临时文件失败: %w", err) |
Copilot
AI
Dec 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potentially excessive file permissions: Setting file permissions to 0o644 (readable by all users) may be more permissive than necessary. Temporary log files could contain sensitive information. Consider using 0o600 (readable only by owner) unless broader permissions are specifically required. If world-readable permissions are necessary for inter-process communication, document the security rationale in a comment.
| // 设置文件权限为644,确保其他进程可以读取 | |
| if err1 := os.Chmod(tempLog.Name(), 0o644); err1 != nil { | |
| // 设置文件权限为600,仅允许当前用户读写,避免临时日志被其他用户读取 | |
| if err1 := os.Chmod(tempLog.Name(), 0o600); err1 != nil { |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -307,26 +307,94 @@ func calculateMD5(header http.Header) string { | |||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // ExtractLocalTempFile 按路径提取临时文件,路径可以是 http/base64/本地路径 | ||||||||||||||||||||||||||||
| func ExtractLocalTempFile(path string) (string, string, error) { | ||||||||||||||||||||||||||||
| // 如果是 files:// 协议且指向本地文件,直接解析并返回 | ||||||||||||||||||||||||||||
| if strings.HasPrefix(path, "files://") { | ||||||||||||||||||||||||||||
| filePath := path[8:] // 移除 "files://" 前缀 | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| var absPath string | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // 处理 files:///path 格式(三个斜杠开头) | ||||||||||||||||||||||||||||
| filePath = strings.TrimPrefix(filePath, "/") | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // 检查是否为有效的绝对路径 | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // 检查是否为有效的绝对路径 | ||||||||||||||||||||||||||||
|
Comment on lines
+320
to
+321
|
||||||||||||||||||||||||||||
| // 检查是否为有效的绝对路径 |
Copilot
AI
Dec 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Path traversal vulnerability: The files:// protocol handler in ExtractLocalTempFile lacks security validation. Unlike the FilepathToFileElement function (lines 445-450), this code does not verify that the resolved absolute path is within allowed directories (cwd, data directory, or temp directory). An attacker could potentially use this to access arbitrary files on the system by crafting a malicious files:// URL with path traversal sequences like "../../../etc/passwd".
Copilot
AI
Dec 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Silent error suppression: The error from os.MkdirAll is being ignored with the blank identifier. If directory creation fails (e.g., due to permission issues), the subsequent os.CreateTemp will fail with a less informative error. While falling back to system temp directory is acceptable, consider logging the error to help diagnose configuration issues in production environments.
Copilot
AI
Dec 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potentially excessive file permissions: Setting file permissions to 0o644 (readable by all users) may be more permissive than necessary for temporary files. Consider using 0o600 (readable only by owner) unless broader permissions are specifically required for inter-process communication. If world-readable permissions are necessary, document the security rationale in a comment.
Copilot
AI
Dec 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect path parsing logic. The condition if strings.HasPrefix(filePath, "/") && len(filePath) > 1 will strip the leading slash from paths like "/home/user/file.txt", converting it to "home/user/file.txt", which becomes a relative path. This is incorrect for Unix absolute paths. For files:///path/to/file, after removing "files://" we get "/path/to/file", then this code removes another "/" resulting in "path/to/file" which is now a relative path, breaking the subsequent absolute path check.
| if strings.HasPrefix(filePath, "/") && len(filePath) > 1 { | |
| filePath = filePath[1:] // 移除开头的斜杠,files:///path -> /path | |
| } | |
| info, err := os.Stat(filePath) | |
| if err != nil { | |
| return nil, fmt.Errorf("文件不存在或无法访问: %w", err) | |
| } | |
| info, err := os.Stat(filePath) | |
| if err != nil { | |
| return nil, fmt.Errorf("文件不存在或无法访问: %w", err) | |
| } |
Copilot
AI
Dec 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Insufficient path traversal protection. The current security check only validates that paths start with cwd, dataDir, or os.TempDir(), but this is vulnerable to symlink attacks and doesn't prevent access to subdirectories outside the intended scope. After calling filepath.Clean() and filepath.Abs(), you should validate the canonical path again. Additionally, the dataDir check is redundant since dataDir is cwd + "/data", which would already match the cwd prefix check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Silent error suppression: The error from os.MkdirAll is being ignored with the blank identifier. If directory creation fails (e.g., due to permission issues), the subsequent os.CreateTemp call will also fail but with a less informative error message. Consider checking the MkdirAll error and returning a specific error message like "创建临时目录失败: %w" to help users diagnose permission or disk space issues.