本卡屬 FR-114 資安修正(母卡 CM-2019),第 5 批「檔案/共用底層/AI/公告/授權/設備/意見回饋」子集 C 卡 5C-1,修 SUMMARY #13(M02-4/M03-13)/#123(M02-9)。#13 高,#123 中。計畫在 docs/features/FR-114-2609-security-fix-dispatch/batches/plan-b5C.md「卡 5C-1」段。
#13 前半(M02-4):使用者上傳的檔案在畫面上「預覽」時,系統只看副檔名決定用什麼方式呈現——上傳一個副檔名是 .png 但內容其實是網頁(HTML)的檔案,預覽時會被當成網頁整份載入,裡面藏的程式碼會在瀏覽器裡真的執行,等於在別人瀏覽器裡跑我們允許的內容。
#13 後半(M03-13):弱點掃描代理程式回傳的報告檔名,系統直接採用代理程式(或呼叫端)自己說的名字存檔,沒有先拿掉路徑、也沒有檢查副檔名是否在允許清單——如果代理程式(或中間人)刻意回一個帶路徑的檔名,有機會存到不該存的地方或覆蓋掉不該覆蓋的檔案。
#123(M02-9):檔案儲存若設定為「本機硬碟」模式,刪除一個檔案時只刪主檔,之前預覽時順手產生的衍生檔(例如把 Word 轉成 PDF 的快取)留在硬碟上沒有一起清掉——同樣的清理邏輯在「物件儲存」模式已經有做,本機模式漏了,是「只修一半」的典型形狀。
首腦核對:
/Users/chouraymond/Projects/Jedicogy/module/jedi-python-package/.claude/worktrees/jedi-wt-fix-security/<套件目錄>(branch fix/security-b1)改,只動自己那支套件的子目錄、只 git add 該子目錄下的檔。 本卡對應 jedi-file-upload/jedi-detection 兩支套件,worktree 建議 wt-fix-b5C-file-upload。jedi-file-upload/jedi_file_upload/api/routes/upload_file_route.py:173-232 UploadFilePreviewAsPDFRoute.get(),整支預覽出口
jedi-file-upload/jedi_file_upload/api/routes/upload_file_route.py:198 主機物件儲存分支:mimetypes.guess_type(f'preview.{_ext}'),_ext 直接取自使用者上傳副檔名
jedi-file-upload/jedi_file_upload/api/routes/upload_file_route.py:221 內建物件儲存分支,同樣寫法重複一次
jedi-file-upload/jedi_file_upload/api/routes/upload_file_route.py:195,199,229-231 三處 as_attachment=False
jedi-file-upload/jedi_file_upload/api/routes/upload_file_route.py:214-218 既有註解:直接送出模式的 mimetype 要用實際副檔名判斷,不可寫死 application/pdf,否則圖片會在 iframe 裡壞掉
jedi-file-upload/jedi_file_upload/api/routes/upload_file_route.py:141-170 UploadFileDownloadRoute,安全對照組:一律 as_attachment + 固定 MIME_OCTET_STREAM
jedi-detection/jedi_detection/app/service/detection_result_handler.py:217 filename = filename_hint or f"detection_report_{agent_task_uid}",filename_hint 來自呼叫端
jedi-detection/jedi_detection/app/service/detection_result_handler.py:218-221 隨後被代理程式回應的 Content-Disposition 覆蓋一次,兩個來源都沒去路徑、沒查白名單
jedi-file-upload/jedi_file_upload/infra/adapter/local/local_file_adapter.py:82-93 delete_file(),刪完主檔就結束,#123 核心
jedi-file-upload/jedi_file_upload/infra/adapter/local/local_file_adapter.py:96-108 delete_files_by_uids(),同樣缺口
jedi-file-upload/jedi_file_upload/infra/adapter/minio/minio_adapter.py:140 物件儲存模式已呼叫 _delete_derived_files()(對照組)
jedi-file-upload/jedi_file_upload/infra/adapter/minio/minio_adapter.py:167 同上,另一呼叫點
jedi-file-upload/jedi_file_upload/infra/adapter/minio/minio_adapter.py:170-181 _delete_derived_files() 函式本體,反查 ref_id 找衍生檔,物件刪除失敗只記日誌不擋主檔刪除(best-effort,抽共用邏輯時要保留這個寬容)
D-b5C-1(預覽允許哪些格式)決策者已裁照建議:html/htm(掃描報告,硬需求)+ pdf + 常見圖片格式(png/jpg/jpeg/gif/webp)允許預覽,其餘一律強制下載;允許清單走套件設定、套件給預設值。