本卡屬 FR-186(Agent 本體資安掃描第二輪),第 3 批 X1:掃描任務執行與工具帳密(Agent repo,14 檔/約 1152 行)。只掃不修。工作坊用
.claude/workshop-prompts/dispatch-<本卡號>.md當開場 prompt 直接啟動掃描。
用 Claude Code 官方 claude-security plugin 掃 Guidant AI Agent(repo evidence-agent)的「掃描任務執行與工具帳密」,找出資安問題,寫成 PM 與新手工程師都看得懂的報告。只找問題、不修問題。
FR-177 掃過(舊卡 CM-3519),之後有改動;這次重掃要回答兩件事:上次修的有沒有守住、新改的程式有沒有新洞。 範圍按業務模組垂直切(入口→流程→資料),權限漏洞常在層與層的接縫上。
guidant_agent/scan/app/task_executor.py
guidant_agent/scan/app/running_tasks.py
guidant_agent/scan/app/task_sinks.py
guidant_agent/scan/app/credential_handover.py
guidant_agent/scan/app/credential_resolver.py
guidant_agent/scan/app/credential_store.py
guidant_agent/scan/app/secret_form.py
guidant_agent/scan/adapters/credential_store.py
guidant_agent/scan/api/routes/credential_route.py
guidant_agent/scan/api/routes/detection_route.py
guidant_agent/scan/ports/secret_fields.py
guidant_agent/scan/ports/connector.py
guidant_agent/scan/app/cancel.py
guidant_agent/scan/app/probe.py
檔數 14、約 1152 行。驗檔數:git ls-files -- guidant_agent/scan/app/task_executor.py guidant_agent/scan/app/running_tasks.py guidant_agent/scan/app/task_sinks.py guidant_agent/scan/app/credential_handover.py guidant_agent/scan/app/credential_resolver.py guidant_agent/scan/app/credential_store.py guidant_agent/scan/app/secret_form.py guidant_agent/scan/adapters/credential_store.py guidant_agent/scan/api/routes/credential_route.py guidant_agent/scan/api/routes/detection_route.py guidant_agent/scan/ports/secret_fields.py guidant_agent/scan/ports/connector.py guidant_agent/scan/app/cancel.py guidant_agent/scan/app/probe.py | grep -v /tests/ | wc -l 應為 14。scope 外的檔不要當發現報;為核對呼叫端翻範圍外的檔可以,報告標「只為查證」。
首腦標的思考起點,不是檢查清單。掃完後 runner 逐條對一遍:工具沒報的,開檔看一眼寫「人工查過:成立/不成立/為什麼」。FR-177 的人工補查抓到的問題不比工具少。(以下沿用 FR-177 舊卡的重點,行號是舊版、以檔名與函式名為準。)
credential_store.py(adapters):3-4 金鑰與密文同目錄:_read_key(create=True) 第一次產生金鑰時檔案權限怎麼設、目錄權限;put :65-83 的 secret_keys 空值保留舊值邏輯——空字串是「不改」還是「清掉」,與 secret_form.validate :89 的 default 處理合起來會不會讓攻擊者送空值把密碼清成預設。credential_handover.py:32-60 store(task):主系統派「交付帳密」任務寫進本機——任務內容走 8443 JWT(A2 掃守門),這裡看帳密欄位有沒有進 log(audit(... tool=code, method="handover") 只記 code 嗎、rejected 的欄位值會不會原樣進 log)、_clear 能不能被用來清掉所有工具帳密(DoS 掃描功能)。task_executor.py:55-142 _run_one:解出來的帳密怎麼交給 connector——看 credential_resolver.py 回的 dict 之後進了 connector.run(params, credentials) 還是被塞進 params;connector port(ports/connector.py)的介面有沒有規定帳密不能進指令列;任務失敗時的 sink.fail(error) 錯誤訊息會不會帶帳密(connector 把指令列印進 exception 是常見病)。task_executor.py:169-190 _get_stream/_download:下載任務附檔的 dest_path 由誰決定、max_bytes 預設多少、下載到哪個目錄;:192 _upload_reports 上傳報告前有沒有過遮罩(掃描報告裡常含目標主機帳號)。running_tasks.py、task_sinks.py:同一 task_uid 重複派會怎樣(並行跑兩次、互相覆蓋結果);request_cancel 任何人都能取消任何任務嗎(呼叫端是主控台 scan_routes 的 cancel,看有沒有驗 started_by)。scan/api/routes/credential_route.py、detection_route.py:這兩支掛在哪個 port(8000 /detection?),守門是 8443 的 JWT 還是別的;detection_route.py:39 與 :65 兩個 POST 收什麼、進哪裡。secret_form.py:47-74 _coerce/validate:型別強轉有沒有把 "true"/1 類的字串變 bool 讓 schema 檢查失效;store_call 包了什麼例外、會不會把 Fernet 解密失敗的細節回給前端。secret_form.save 的 pinned_keys——確認修法還在、沒被後來的 commit 弄回去、也沒有旁路。FR-177 25 棒報告在 Agent repo docs/security-scan/FR-177/scan-*.md,已登記的 22 條在主系統 repo docs/features/security-scan-consolidated/README.md §3.1 第 219~240 項(全部已修)。已修而且修法成立的不重報;修法不完整、或同一族換個欄位又出現,才報並註明對應項次。