本卡屬 FR-186(Agent 本體資安掃描第二輪),第 2 批 K1:主控台守門殼、頁面與紀錄路由(Agent repo,10 檔/約 984 行)。只掃不修。工作坊用
.claude/workshop-prompts/dispatch-<本卡號>.md當開場 prompt 直接啟動掃描。
用 Claude Code 官方 claude-security plugin 掃 Guidant AI Agent(repo evidence-agent)的「主控台守門殼、頁面與紀錄路由」,找出資安問題,寫成 PM 與新手工程師都看得懂的報告。只找問題、不修問題。
FR-177 掃過(舊卡 CM-3516, CM-3518),之後有改動;這次重掃要回答兩件事:上次修的有沒有守住、新改的程式有沒有新洞。 範圍按業務模組垂直切(入口→流程→資料),權限漏洞常在層與層的接縫上。
guidant_agent/console/api/__init__.py
guidant_agent/console/api/pages.py
guidant_agent/console/__init__.py
guidant_agent/console/app/body_limit.py
guidant_agent/console/app/inline_policy.py
guidant_agent/console/app/view_audit.py
guidant_agent/console/migrations.py
guidant_agent/console/api/log_routes.py
guidant_agent/console/api/keys_routes.py
guidant_agent/console/api/runs_routes.py
檔數 10、約 984 行。驗檔數:git ls-files -- guidant_agent/console/api/__init__.py guidant_agent/console/api/pages.py guidant_agent/console/__init__.py guidant_agent/console/app/body_limit.py guidant_agent/console/app/inline_policy.py guidant_agent/console/app/view_audit.py guidant_agent/console/migrations.py guidant_agent/console/api/log_routes.py guidant_agent/console/api/keys_routes.py guidant_agent/console/api/runs_routes.py | grep -v /tests/ | wc -l 應為 10。scope 外的檔不要當發現報;為核對呼叫端翻範圍外的檔可以,報告標「只為查證」。
首腦標的思考起點,不是檢查清單。掃完後 runner 逐條對一遍:工具沒報的,開檔看一眼寫「人工查過:成立/不成立/為什麼」。FR-177 的人工補查抓到的問題不比工具少。(以下沿用 FR-177 舊卡的重點,行號是舊版、以檔名與函式名為準。)
console/api/__init__.py 的 require_session(scope):scope 參數是字串或 tuple 時各怎麼判;不帶 scope 時只驗登入——哪些路由不帶 scope(grep -n 'require_session()' )、是不是都該只驗登入;acting_as 把 session 裝進 g 之後有沒有在 teardown 清掉(thread 重用時下一個請求撿到上一個人的身分);cookie 屬性 :144-145 第一期已核過,這裡看 CSRF:主控台有沒有 CSRF token 或靠 SameSite=Strict 就夠。pages.py:56 /<path:page> 與 :63 /assets/<path:filename> 的 send_from_directory:path 能不能帶 .. 跳出 assets 目錄(werkzeug 會擋,但 Path(...) / "assets" 這種拼法先確認);:45 CSP nonce 怎麼產、每次請求都新的嗎。ops_routes.py:149 download_support_bundle(configure scope):診斷包內容由 platform/support_bundle.py 決定(B7 掃),這裡看回應有沒有 Content-Disposition 檔名注入、有沒有尺寸上限;:234 reset_storage 會清掉儲存設定含金鑰——是 POST 且 configure scope 嗎、有沒有二次確認。ops_routes.py:88 put_offline_login、:101 put_agent_name、:217 put_storage:body 欄位白名單有沒有(多塞欄位會不會被 **body 展開存進去);body_limit.json_body() 上限多少。runs_routes.py/log_routes.py:執行紀錄與 log 的讀取有沒有依 started_by/sub 過濾,還是任何登入者看全部;log 路由回的內容有沒有過遮罩(密碼、token 會不會原文出現);分頁參數能不能被塞成超大 limit。keys_routes.py:34 renew_now:任何 configure 的人都能觸發換證——換證有頻率限制嗎(連打會不會把主系統簽發站打掛、或讓本機一直處在換證中)。console/__init__.py:console 模組怎麼註冊到 8444、是否也被掛到 8000/8443(ARCHITECTURE 說只掛 8444,驗一下)。inline_policy.py:69-104 decide/html_preview/apply_headers:HTML 只在「檔名 .html 且內容真是 HTML」時 inline 並帶 CSP sandbox(:86)——SVG 呢(SVG 可帶 script,image/svg+xml inline 等於 XSS);_magic_mime 用什麼判檔頭、只讀前幾 KB 會不會被「前面塞 PDF 檔頭、後面是 HTML」繞過;CSP sandbox 字串有沒有 allow-same-origin(有就讀得到 cookie);apply_headers 有沒有 X-Content-Type-Options: nosniff。body_limit.py:23-31 read_limited:先看 content_length 再 stream.read(max+1)——chunked 傳輸沒有 content_length 時走哪條;guard 掛在哪些 blueprint、有沒有漏掛的(直傳 8444 的 blob 上傳走別條,確認 files 模組自己有上限)。heartbeat.py:98 _local_admin_password() 與 :130-132 fields():心跳送回主系統的欄位有哪些——「本機管理員有沒有設密碼」這種狀態要不要出去;console_allow_cidr.get().status_fields() 會不會把安裝時的網段基線(內網拓撲)送到主系統(對照 memory「新增資料出口先查同一份資料在既有端點的守門」)。