本卡屬 FR-177(母卡 CM-3507),第 8 棒 A8:證據檔:blob API、瀏覽器直傳 8444、儲存設定、下載加密(Agent repo,19 檔/約 1225 行)。只掃不修。工作坊會用
.claude/workshop-prompts/dispatch-<本卡號>.md當開場 prompt 直接啟動掃描,小弟不必自己打指令。
用 Claude Code 官方 claude-security plugin 掃 Guidant AI Agent(裝在客戶機器上的那支程式,repo evidence-agent)的「證據檔:blob API、瀏覽器直傳 8444、儲存設定、下載加密」這一塊,找出資安問題並寫成 PM 與新手工程師都看得懂的報告。只找問題、不修問題,修是另外開卡的事。
證據檔在 Agent 上的進出:主系統或掃描工具存進來(blob API)、使用者從瀏覽器直接上傳到 Agent(8444,拿主系統簽的一次性票券)、檔案存到哪(本機或客戶的 S3/MinIO)、下載時加密打包。
證據檔是客戶最敏感的資料(掃描報告、設定檔、系統清冊)。直傳 8444 是刻意開給瀏覽器的面,票券驗錯就是匿名上傳;儲存設定裡有客戶物件儲存的金鑰;下載加密若用弱密碼等於沒加密。memory 記過「橫切需求漏掉 jedi-file-upload 的下載出口」,這裡的檔案邏輯也在 jedi-file-upload 裡,本棒要看 Agent 包它的那層有沒有多開門。
guidant_agent/files
檔數 19、約 1225 行。驗檔數:cd <工作目錄> && git ls-files -- guidant_agent/files | grep '\.py$' | wc -l 應為 19。scope 外的檔不要讀(研究員會越界,越界的發現首腦驗收時會挑掉)。
首腦讀過程式碼後認為最容易出事的地方,是思考起點不是檢查清單。工具不會照這份走,掃完後 runner 要自己逐條對一遍:工具沒報的,開檔看一眼寫「人工查過:成立/不成立/為什麼」。前幾輪最嚴重的發現(FR-076 L2 的 HIGH)都是 runner 照這清單追出來的,不是工具報的。
browser_plane.py:106-120 _verify_ticket:票券綁 agent_uid+scan_uid,重放靠 TicketReplayGuard(:134)——guard 是記憶體的嗎(重啟就忘、多 worker 不共享);票券 exp 多長;:145 CORS origin 從票券 claims 來,沒有時退回 request.headers.get("Origin")——這條退路等於任何 origin。browser_plane.py:69-72 secure_filename 處理檔名與副檔名後,實際落地路徑怎麼拼;:83-103 串流算 sha256 與 max_bytes 上限——超過時已寫入的部分有沒有清掉;content-type 有沒有白名單(HTML/SVG 上傳後被主控台當頁面開就是 XSS)。blob_route.py:96/:143/:149 三處 send_file:uid 怎麼對到路徑(有沒有 ..);:143 把檔案轉 PDF 預覽——轉檔器是什麼、吃的是任意上傳內容嗎;下載端點要什麼身分(主系統 JWT/主控台 session/都不要)。storage_settings.py:S3/MinIO 的 access key 存哪、回傳設定給主控台時遮不遮;endpoint 能不能設成 http 或內網任意位址(SSRF+金鑰外送);storage_trust.py 的 CA 設定能不能關掉驗證。file_protect.py:66 下載加密密碼只驗非空與 ≤128——用的加密是 zip 傳統加密(ZipCrypto,可破)還是 AES;密碼從哪來(使用者輸入?隨機產生?);:47/:59 稽核事件記了 file_name——有沒有連密碼一起記進 log。files/__init__.py 與 app/ports.py:8444 掛了哪些 blueprint——除了直傳與主控台,有沒有 blob 下載也掛在 8444 上但只靠 CIDR 白名單不驗身分。customer_files_repo.py、migrations.py:SQL 有沒有拼字串;檔案列表查詢有沒有依 scan/tenant 過濾。FR-086 B1(主系統 jedi-file-upload HTTP 邊界)四條同病「只驗身分不驗歸屬」(CM-1652 已驗);FR-077 R2b 主系統側「下載端點零認證、租戶由攻擊者給的編號決定」(併 CM-1595 已修)。Agent 側從未掃過。