Guidant AI 資安檢視總報告

文件首腦交接(第二棒 → 第三棒)

23 份模組報告已全數產出,九份完成內化修訂。這份交接文件說明現在到哪、怎麼接、有哪些坑——第二棒新增了三個坑,其中「卡片本身會寫錯」那條踩了三次。

§1

你是誰

你是文件產出線的首腦。決策者(講者)下指令給你,你分析、判斷、派 subagent 執行、驗收 subagent 的產出。

另一條線是「內化首腦」——陪決策者逐塊讀懂報告、釐清問題、記錄他的判斷,產出是 Notion 卡。

分工:內化那條線產出「要改什麼」的卡片 → 你負責把卡片落實進文件、驗證事實、管格式與 build。


§2

現在到哪

狀態
23 份模組報告 ✅ 全數產出
完成內化修訂 9 份(M01 遠端代理、M02 檔案上傳、M03 弱點檢測、M05 問卷、M06 稽核流程、M07 證據分類、M08 防竄改、M19 設備清冊、M22 系統設定)
單點裁定 M14 AI 聊天助手第 1 條(裁定要修、與 AI 儀表板合併)
待內化 14 份
收尾章節 ⬜ 未開始(一頁摘要、問題總表重整、分析結論、修正建議)

索引表的順序就是閱讀順序(按嚴重度)。已完成的九份不在待辦內,下一塊照索引表往下走。

第二棒處理過的卡(全部已 commit、已回寫 Notion、狀態「修正待驗證」)

卡 內容
CM-1984 M08 全頁一致性補掃
CM-1985 M22 七項施工 + 第七節追加
CM-1988 全站裁定(一):出貨前定位/拿掉行號/M01 M02 回頭修
CM-1989 M06 第 3 條重寫、第 4 條降級、新增兩條 + 第八、十節定級與上限
CM-1990 M05 招牌數字更正 7/7 對 0/7
CM-1991 M07 舊線整組退役
CM-1993 M03 十二項
CM-1994 全站裁定(二):本輪掃描止損定調
CM-1996 M19 裁定推翻舊決定 + 「補權限會擋掉誰」

未 push——全部等決策者明確指示。


§3

工作循環(每塊都一樣)

  1. 內化首腦跟決策者過完一塊 → 開一張 Notion 卡(含逐條更正、決策、施工清單)
  2. 決策者把卡號轉給你
  3. 你讀卡片全文:python3 scripts/notion_case.py get CM-XXXX
  4. 自己先查證關鍵事實——特別是「報告寫錯了」這類,那是要寫進稽核報告的
  5. 派 subagent 執行,驗收回報
  6. 有需要決策者裁定的,先問,不要替他決定

§4

🔴 已經踩過的坑(別再踩)

一、不要只信文件,要回程式碼驗

決策者質疑過「應該不是整份從 feature 複製下來吧」。那之後改成每條發現都要回程式碼確認,結果抓到六處總表寫錯或過期:

  • 一條已修的被記成未修(稽核輪次的簽核權限)
  • 一個查不到出處的數字(原記「122 支入口零權限檢查」,重數 89)
  • 一條實測數字已歸零(客戶資料隔離當年 39/213 筆,重測全 0)
  • 一條總表記未修、實際已修(日誌保存期限)
  • 一處持有者人數不符(原記 8 個、實查 9 個)
  • M08 一句稽核方查得出來是錯的評級理由

二、curl 拿到 200 不代表頁面存在

文件站的 404 fallback 回的是首頁、狀態碼 200。我曾因此得出完全相反的結論(「密碼一頁都沒外洩」,實際是 33 頁全部外洩)。

正確驗法:curl -sL(跟隨轉址)+ 加 cache-buster + 比對 404 fallback 的 md5。

三、subagent 讀大檔會爆 context

有一棒因為整包讀大檔失敗(autocompact thrashing)。派工時要寫明:用 sed -n 分段讀,不要整包 cat。

四、工作樹有別人的未提交變更

派工單必寫:顯式 git add <檔名>,禁用 -am。


§5

🔴 第二棒新增的三個坑

五、🔴 卡片本身會寫錯——關鍵數字一定要自己開程式碼驗(踩了三次)

內化那條線的卡片是人寫的,數字會錯。第二棒三次抓到:

卡 卡片寫的 實際 後果
CM-1991 舊線「9 支端點」 10 支功能、11 個進入方式、14 條網址 卡片自己列的名字就是 10 個,總數寫 9 是筆誤
CM-1993 「七支讀取」是報告寫錯 卡片說的八支正確(實數 18 支、掛 10 支、沒掛 8 支) 報告照抄原始技術報告自己數錯處
CM-1990 招牌數字 6/6 對 0/8 要改成 7/7 對 0/7 卡片正確,實查守門呼叫點剛好七處 這句最可能被現場翻程式碼對帳

判準:凡是會寫進報告、會被稽核抽查的數字(幾支端點、幾張表、幾個檔案、幾個角色),自己 grep 或開檔數一次,不要讓 subagent 照抄卡片。派工單要明寫「用這個實數,不要用卡片的數字」。

六、🔴 卡片會在你做完之後追加節次——讀卡要讀全文

CM-1985 做完後追加第七節、CM-1989 做完後追加第八、十節。只看「給文件首腦的施工清單」會漏掉。

做法:python3 scripts/notion_case.py get CM-XXXX 之後,先 grep 全文看有幾個 ## 節次,確認施工清單是不是最後一節。決策者轉卡號給你時說「處理第十節」,也要順手看看第八、九節是不是也是新的。

七、runner 紀律三件事,Notion 回寫最容易漏

做完卡片要做三件:① 顯式 git add + commit ② Notion 子卡 append 白話補充(做了什麼/commit hash/驗證方式)③ 子卡狀態改「修正待驗證」。

第二棒前三張卡只做了 ①,後來補回寫。漏掉 ②③ 的後果:決策者看不到進度、平行 session 拿到過期世界觀。派工單沒寫這三件也要做,那是 runner 鐵律不是選配。


§6

決策者定過的通則

事項 裁定
風險等級 一律以 Notion 工單為準,報告頁與工單不一致時以工單為準(不用再問)
push 一律等決策者明確指示,不要自己 push
切 branch 不切,永遠在當下 branch
Notion 卡 微量作業用 subagent 即可不必開卡;太大才開
待決事項 不要替決策者決定,寫進文件標「待定」

§7

文件規格

  • 模組頁規格:docs/security-report/_module-page-spec.md(五段結構、七欄定義、十種分類、白話禁用詞表、自檢清單)
  • 白話標準:讀者是 PM 與老闆。「白話」不是把句子講得口語,是讀者完全不需要技術背景就能懂
  • 禁止寫:「已確認安全」「沒有漏洞」「全面檢視」——我們的方法不能宣稱這個
  • 不要寫進實際值:帳號名、位址、埠號、私鑰——講類型即可(這份之後要收斂成對外版)
  • build:python scripts/deliverables/render_index.py docs/security-report/ --site-root docs/security-report/

§8

還沒做的事

一、側欄順序與索引表不一致

索引表按嚴重度排,側欄按檔名編號(M01~M23)排——編號是當初派工分批給的,與嚴重度無關。

重編號的對照表已算好,但沒做,因為:① 內化過程中嚴重度還在變(已有兩條改判)② 改名會撞到正在跑的修訂。建議內化全部完成後一次做。

二、收尾章節

23 塊都過完才寫得準:

  • 一頁摘要(首頁最上面,給只看一頁的人)

  • 問題總表重整(141 條按嚴重度重排,現版在 docs/features/security-scan-consolidated/risk-overview.md)

  • 分析與結論——跨模組的問題型態,內化至今累積七組:

    • A 組「只驗登入、不檢查歸屬」(最大一組,M05 一塊就貢獻七條)
    • B 組「鑰匙掛在牆上」(密碼進版控、進公開文件站)
    • C 組「想到了,只做了一半」(M01 第 1 條、M02 第 5 條、M05 問卷、M08 第 2 條)
    • 「信任鏈的起點沒人守」(M08 第 1 條,驗證工具自己不在被驗證範圍內)
    • 「客戶層級的權限,改到的卻是全系統共用的那一份」(M22 第 1 條 + M09 日誌,已裁定兩條套同一條規則)
    • 「宣告了權限,只有畫面在認」(M03 第 8 條、M19 第 1 條都已裁定後端補檢查;M23 意見回饋尚未裁)
    • 「東西寫對過,但被重做的時候沒跟上」(M06 套件有檢查、主系統重寫的漏了;M08 代理程式那頭三層、我們這頭零層)
    • 🆕 正面對照組(M19):它的守門是「吵鬧拒絕」——少了必要零件直接拒絕啟動、錯誤訊息還寫明後果。與另一塊「零件沒接上就靜默放行」正好相反。收尾講「同樣的問題為什麼有的塊有、有的塊沒有」時,這是最好的對照
  • 🔴 〈檢視方法與工具〉要補一段(CM-1994 第五節建議,第二棒未做——屬收尾範圍):內化第四棒逐條開檔查證,抓到 18 處報告與事實不符(M05 4 處、M07 8 處、M03 6 處),每一塊都至少有一處會誤導施工或誤導判斷。這不是「報告寫得爛」,是工具產出的價值在「指出哪裡要看」,不在「結論可以直接用」——與止損裁定是同一個故事。在稽核場合是加分的:它證明我們不是把工具輸出照單全收,每一條都有人回去開檔核對過。

  • 修正建議(只列優先順序,不寫日期——時程是決策者跟 PM 排的)

三、業界標準的兩項補強(不急)

報告開頭的封面基本資料、風險評級標準的說明。


§9

🔴 第二棒期間生效的全站變更(接手前一定要知道)

一、報告定位改了:這是「出貨前的最後檢查」

產品從未出貨給任何真實客戶。 已寫進首頁最前面(CM-1988)。141 條問題全部沒有影響過任何一個真實客戶。

🔴 判準(最容易做錯,第二棒花最多篇幅在這件事):這不是「把所有講到密碼外流的地方都改掉」。每遇到一句先問:

這個東西是「隨產品出給客戶的」,還是「我們自己在用的」?

  • 隨產品走的 → 沒出貨就沒外流過 → 改
  • 我方自有基礎設施(公開文件站、程式碼倉庫、我們自己的測試機/展示機、內部套件倉庫)→ 與出貨無關、曝光可能真的發生過 → 不改,嚴重性一字不動

目前保住未動的五條:M15 第 6 條、M17 第 8/10 條、M23 第 1 條、M16 第 7 條。M01 第 5 條另加了一句聲明「與產品出不出貨完全無關,嚴重性不降」防止被誤讀。

二、本輪掃描止損定調(CM-1994)

舊講法「是時間與資源的取捨」已全站清除(首頁、M10、M11、M12、GUIDE-01)。新講法是:

檢視工具本身不可靠,我們判斷繼續投入不划算,改成針對已經發現的修。

差別在於——舊講法聽起來像便宜行事,稽核方會追問「那為什麼不多給時間」;新講法是專業判斷,而且我們手上有證據(17 小時換 25 次人零產出、紀錄被誤刪、派三位回一位)。

接手後若看到任何一頁還寫著舊講法,那是殘留,要改。

三、程式行號已全站拿掉,只留檔名

決策者裁定(CM-1988):讀者是 PM、老闆、稽核方,他們不會去對行號;要對行號的工程師看需求中心的原始技術報告就有。留著只會過期,稽核方拿著對不上的行號來問是扣分的。


§10

還沒清的待決事項(第二棒留下的)

# 事項 誰裁
1 M01 第 3 條定案選①的代價沒人接——「管理頁顯示發出多久、用過幾次」要有人定期去看才有用,目前沒指定負責人 決策者
2 M01「出貨流程加自動密碼檢查」性質變了——原本同時撐著「換密碼」與「加檢查」,換密碼已結案,只剩加檢查,優先度可能要重評 決策者
3 M23 意見回饋那塊的「宣告了權限只有畫面認」尚未裁(M03、M19 都已裁定後端補檢查) 決策者
4 M03 體質第 6 條(分頁工具跨欄位條件用「或」)要另開獨立卡——那是產品行為決定不是資安問題 決策者
5 同步功能那三件(公開可編輯的資料夾、建資料夾端點沒後端守門、Google 審核 4–12 週)——不屬於任何模組頁,時間壓力最大的是審核那件 決策者

§11

已知但決策者裁定不處理的

  • 資料庫密碼散在 249 個版控檔(66 個在會發佈的目錄,33 個網頁線上可見)——決策者裁:該站之後用存取限制擋住、密碼是內部開發用、會換密碼。已知問題,不用再提
  • M08 第 4 項(行號失效)——已裁定並執行(CM-1988):全站拿掉程式行號只留檔名。實際範圍遠小於預期,23 頁只有一處

§12

座標

報告站 docs/security-report/(md 是源,html 是產物)
原始技術報告 需求中心 21 個 FR 站,不要改那邊
跨模組總表 docs/features/security-scan-consolidated/(README.md + risk-overview.md)
Notion 工具 python3 scripts/notion_case.py get CM-XXXX
三個 repo 主專案(工作目錄)/~/Projects/Jedicogy/module/jedi-python-package//~/Projects/Billows/Audit-Manager/compliance-manager-fe
開發資料庫 localhost:5432、guidant_ai_dev、.env 裡的 cmmgr,只能 SELECT