Skip to content

fix: prevent path traversal error when knowledge FilePath is empty#1658

Open
ChenRussell wants to merge 1 commit into
Tencent:mainfrom
ChenRussell:fix-savefile-error
Open

fix: prevent path traversal error when knowledge FilePath is empty#1658
ChenRussell wants to merge 1 commit into
Tencent:mainfrom
ChenRussell:fix-savefile-error

Conversation

@ChenRussell

Copy link
Copy Markdown
Contributor

Description

  • 现象

    调用 /api/v1/knowledge/{id}/preview 返回 HTTP 500:

  {
    "error": {
      "code": 1007,
      "message": "Failed to retrieve file",
      "details": "invalid file path: path traversal denied: path is outside base directory"
    }
  }

关键日志:

  [local.go:112] Getting file:           ← filePath 为空
  [local.go:117] Path traversal denied for GetFile: path traversal denied: path is outside base directory
  • 根因

    数据库中有一条 knowledge 记录的 file_path 为空字符串。

    这条脏数据的产生过程:

    CreateKnowledgeFromFile
    ├── CreateKnowledge() ← 先入库,FilePath 此时为空
    ├── SaveFile() ← 存文件失败(磁盘满/权限等)
    └── return nil, err ← 直接返回,knowledge 记录未清理

    CreateKnowledge 和 SaveFile 不是原子操作。SaveFile 失败后 knowledge 已入库但 FilePath 为空,成为孤儿脏数据。

    当预览该知识时,空 FilePath 经过 normalizePathForBase 处理:

  clean := filepath.Clean(strings.TrimSpace(""))  // → "."
  return clean                                      // 返回 "."

接着 SafePathUnderBase(baseDir, ".") 将 "." 解析为当前工作目录。当进程工作目录与 baseDir 不同时,被误判为路径遍历攻击,报出误导性错误。

  • 修复

    1. GetKnowledgeFile 增加 FilePath 空值守卫,返回明确错误:拦截脏数据,避免误导性错误
    2. normalizePathForBase 空路径返回 s.baseDir 而非 ".": 兜底,防止 . 被解析为当前工作目录
    3. SaveFile 失败后删除孤儿 knowledge 记录:源头杜绝脏数据产生

Type of Change

  • 🐛 Bug fix

Related Issue

Fixes #

Testing

Checklist

  • make fmt && make lint && make test pass locally
  • Self-reviewed the code
  • Added/updated tests covering the change
  • Updated related documentation (README, docs/, Swagger annotations, etc.)
  • Breaking changes are clearly called out in the description above

Screenshots / Recordings

   Three related fixes for the issue where a knowledge record with empty
   FilePath (from a failed SaveFile during upload) caused a misleading
   "path traversal denied" error when trying to preview the file:

   1. GetKnowledgeFile: add guard to return a clear error when FilePath
      is empty, instead of letting it fall through to the storage layer.

   2. normalizePathForBase: return baseDir instead of "." when the input
      is empty or whitespace-only, preventing SafePathUnderBase from
      resolving "." to the current working directory (which may differ
      from baseDir).

   3. CreateKnowledgeFromFile: delete the orphan knowledge record when
      SaveFile fails, preventing FilePath-empty records from persisting
      in the database.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant