Guidant AI 資安檢視總報告 · 第一章
這一章回答一個問題:這份報告憑什麼可以相信? 我們怎麼查的、用了什麼、哪些地方查得徹底、哪些地方我們老實說「還沒查」。
我們請 AI 把整套系統的程式碼一行一行讀過去,像找碴一樣挑出可疑的地方;每挑出一個疑點,再另外找三個獨立的 AI 重查一遍投票表決;最後由人親自把每一條打開來確認。
為什麼要這麼麻煩? 因為資安問題分兩種:
用了過時的零件、密碼直接寫在檔案裡。 這種有現成工具可以自動掃,快又便宜,我們 7 月做過一輪。
程式寫得完全正常,只是忘了問一句「這筆資料是你的嗎」。 自動工具永遠掃不出來——因為程式沒有寫錯,是漏寫。
這次要找的是第二種。代價是慢、貴,而且不能保證每個角落都看過——這一點我們在最後一節老實交代。
為什麼要拆這麼多道手續
讓 AI 單獨去找漏洞,會犯兩種錯:看走眼說有(其實沒事),和讀漏了說沒有(其實有洞)。
前者靠「三個人獨立重查投票」擋下,後者靠「人親自逐條核對」補上。兩道都做,結論才站得住。
負責主導的人(下面稱統籌者,也是最後為結論負責的那個人)會先自己把這批程式讀一遍,圈出「最可能出事的五到八個地方」,寫成一份工作單。
這一步是刻意的——如果不先圈,AI 會漫無目的地找;圈了之後,等於先告訴它「這幾個地方我特別懷疑,你去驗給我看」。
這個人開一個獨立的環境準備動工。他不負責按下開始鍵——他只先核對「要查的東西數量對不對」,對完就停下來回報。
這個工具刻意設計成「AI 自己叫不動」
必須由人本人當場打字下令,而且要打一句「我知道這會跑很久、會花不少錢」才會開始跑。
工具的作者不希望 AI 在人沒注意的時候,按下一個要跑好幾小時、花掉大筆費用的按鈕。
副作用是:這件事沒辦法排在半夜自動跑,一定要有人在。
AI 把這批程式從頭讀到尾,挑出它覺得可疑的地方。
它的標準偏嚴——要能講得出「壞人具體要怎麼做才能得手」才會提出來。所以它比較容易漏掉,不太會亂報;報出來的通常都是真的。
找出疑點的那一個,不能自己說了算。
每一個疑點,都會另外找三位重新查證——他們彼此不認識、也看不到前一位的推理過程,各自從頭把相關的程式看過一遍,再各自說「我認為這是真的問題」或「我認為不是」。
| 三票結果 | 怎麼處理 |
|---|---|
| 三票都說是 | 這個問題成立 |
| 兩票說是、一票說不是 | 成立,但反對的理由會記下來——通常會影響我們判斷它有多嚴重 |
| 三票都說不是 | 當作誤判,不列入 |
這一關是有牙齒的,不是走過場
有一次四個疑點裡被否決了兩個,否決的理由具體到打開程式指出:「這裡最多只能填六個欄位,多填會直接報錯,根本塞不進東西。」
AI 全部跑完之後,統籌者還要自己做三件事:
不是看 AI 的結論,是自己把那段程式叫出來、順著追到最外面的入口,確認真的沒有人在把關。最嚴重的那幾條,要把「壞人從第一步到得手」整條路走一遍。
第 1 步圈出的那五到八個懷疑,AI 經常一個都沒回答。這些要人自己回頭查,而且報告上要註明「這是人查的,不是 AI 找到的」。
AI 為了搞懂前因後果,常常會跑去讀不在這次範圍內的程式,然後把別人家的問題當成這次的發現報上來。有一次九條發現裡,八條其實是別批已經報過的。
重查的那三位只管「這個問題是不是真的」,不管「這是不是這次該查的」——所以要人拿範圍清單一條一條比對挑掉。
一次檢視通常要一到兩個小時,最久的一次跑了五個半小時。
我們不是「把整個系統丟進去查一次」,而是切成很多小批。這不是謹慎,是不分批根本跑不完。
一次貪心,全軍覆沒
曾經有一次,我們一口氣放了 42 個檔案進去。結果負責重查的 105 個 AI 全部超過用量上限被中斷,21 張票一張都沒投出來——那一次等於白跑。
後來又有一次,連續試了五次全部無功而返,才把上限再往下收。
現在的規矩是兩條,哪條先到就停:一批不超過 15 個檔案,而且不超過兩千行程式。
一般人會以為「讀程式找漏洞」最花資源。其實不是——最花的是重查投票:找出幾個疑點,就要另外找幾組三個人,每一位都得從頭把程式再讀一遍。
而疑點的數量大致跟範圍成正比。所以範圍放大一倍,成本不只放大一倍。
照功能切,不照技術層次切
每一批拿一個完整功能,從「使用者按下按鈕」一路追到「資料存進資料庫」。
因為權限漏洞最常躲在銜接處——只給上半截或只給下半截,兩邊都看不出問題,合起來才看得到。
真的切不開的時候,寧可讓相鄰兩批重疊、把銜接的部分都帶進去,重複報的再由人挑掉。銜接處沒人看,才是真的漏掉。
有些功能的程式一半在外部模組、一半在我們主系統。工具一次只能看一個程式庫——範圍跨兩邊時,另一邊的檔案會被安靜地丟掉,不報錯、不提醒,看起來就像「那些檔案查完沒事」。
所以這種範圍一律配對切成兩次掃:模組那邊一次、主系統那邊一次,再由執行者手動核對兩邊接起來的地方(主系統傳了什麼給模組、模組回了什麼)。稽核輪次管理那塊九輪全部這樣做,其中一條問題(稽核計畫 Word 的壓縮炸彈)兩邊各自獨立掃到,正好互相印證。
真正的判準是「要讀進去多少東西」。有一個兩千五百行的單一檔案順利跑完了,反而有一批一千五百行、但分散在五個檔案的連續失敗六次——因為要在五個檔案之間來回翻。
中文註解特別多的部分,同樣行數要消化的量是英文的兩三倍。
每跑完一次,工具會自動留下一張紀錄,寫著這次找出幾個疑點、投了幾票、以及有沒有完整跑完。
這張紀錄是我們判斷「這次結果能不能採信」的依據。
「沒跑完」有三種,意思完全不同——不能一律當失敗
| 哪一種 | 實際狀況 | 能不能採信 |
|---|---|---|
| ① 重查完全沒跑起來 | 一票都沒投出來 | 不能說「這裡查過了」。可以靠人工核對開工單修,但不能宣稱檢視過 |
| ② 中途超過用量、恢復後接著跑 | 工具記下中斷的,額度恢復後用完整三人重投 | 這其實不算失敗,票數是完整的,照常採用 |
| ③ 跑完了但存檔出錯 | 投票完整跑完,只是最後存檔時有幾條的路徑寫錯被退掉 | 是存檔問題不是查證問題,以人工報告為準,被退的補回去即可 |
所以看到「沒跑完」要先看是哪一種,不能直接當成白跑。
還有一個陷阱:一個疑點都沒找到的時候,紀錄上也會顯示「完整跑完」——那是「沒東西可投票」,不是「這裡很乾淨」。這種情況我們會另外標出來。
%%{init: {"theme":"base","themeVariables":{"background":"#ffffff","primaryColor":"#eef2ff","primaryTextColor":"#1e293b","primaryBorderColor":"#6366f1","lineColor":"#64748b","secondaryColor":"#f1f5f9","tertiaryColor":"#f8fafc","fontFamily":"ui-sans-serif, system-ui, sans-serif","fontSize":"14px"}}}%%
flowchart LR
A["提出疑點<br/>(要說得出壞人怎麼得手)"] --> B{"三個人<br/>獨立重查投票"}
B -->|"三票否決"| D["不列入<br/>但人仍會看一眼"]
B -->|"通過"| C["人親自核對<br/>打開來看/挑掉不屬於這批的/重新評估嚴重度"]
C --> E["列入問題總表<br/>一句白話結論"]
被否決的也要看一眼。 重查的人判斷「現在打不到」通常是對的,但他只回答了「現在打不打得到」,沒有回答「這段程式本身是不是寫錯了」。
有一次,一個被三票一致否決的疑點,統籌者核對後發現:他們說「打不到」完全正確,但漏看了同一段程式裡兩行用了不同的東西在比對——那是另一個問題,只是不會被壞人利用。
也有反過來往上調的:有一個問題,重查的人只敢說「中等把握」,因為卡在一件要查資料庫才知道的事。統籌者真的去查了,確認成立,把把握度提到「高」。
用的是 Claude Security——Claude Code 官方推出的資安檢視外掛,由 Anthropic 開發。
白話說,它做的事是:派出幾十個獨立的 AI 去讀程式碼,一部分負責找問題,一部分負責重查投票,跑完產出一份報告和一張「有沒有做完」的紀錄。
| 官方原始碼與說明 | anthropics/claude-plugins-official → plugins/claude-security |
| 產品介紹頁 | claude.com/product/claude-security |
| 目前狀態 | 公開測試版(beta),所有 Claude Code 使用者都能裝 |
| 我們用的版本 | 0.10.2.3(官方已出 0.11.0,我們刻意不升——比對過差異只動報告格式,對眼前的問題沒幫助) |
它是 Anthropic 另一項雲端服務的**「在自己電腦上跑」的版本**:同樣的檢視能力,但整個過程都在我們自己的環境裡完成,程式碼不會傳出去。
官方自己講明的三件限制(我們照單全收,也寫進這份報告)
另外兩個設計,直接支撐了這份報告的可信度:
那一次用的是三個性質完全不同的工具:
| 工具 | 它是什麼 | 負責什麼 |
|---|---|---|
| Semgrep | 一本「危險寫法字典」,拿去比對程式碼,命中就報 | 程式裡的危險寫法。後端一次比對了 1,144 條規則 |
| Trivy | 一張「成分表對照器」——把我們用到的現成零件版本,去對全世界公開的已知漏洞清單 | 零件有沒有已知漏洞、密碼有沒有寫死在檔案裡 |
| SonarQube | 一個長期駐點的「健康檢查站」,常態盯著整個系統的品質 | 問題數量的長期追蹤 |
那一次的成果:後端高風險的零件漏洞從 15 個降到 0,前端從 83 降到 18。
查「寫錯了嗎」上一次:拿字典比對
查「漏了嗎」這一次:讀懂了再判斷
| 上一次 | 這一次 | |
|---|---|---|
| 找得到什麼 | 零件過舊、用了危險的寫法、密碼寫在檔案裡 | 忘了檢查資料是不是你的、權限判斷寫反了、要繞三個功能才能拼出來的攻擊路線 |
| 快慢與成本 | 快、便宜,每次改程式都能跑 | 慢、貴,一次要一兩個小時 |
| 定位 | 日常把關 | 定期深度檢視,不是全面保證 |
為什麼非得做這一次不可
因為自動工具永遠找不到這次找到的東西——程式寫法完全正常,錯在漏了一道判斷。
最乾淨的例子:問卷功能裡,六個「寫入」的入口全部有檢查權限,八個「讀取」的入口一個都沒有。同一個檔案裡、寫法一模一樣,差別只在有沒有多問一句「這是你的嗎」。
字典比對看不出這種事——因為沒有任何一條規則會說「這裡少寫了一行」。
這一節是刻意寫的。 知道它哪裡不可靠,才知道哪些結論要打折、哪些地方一定要人補上。
| # | 盲點 | 後果 |
|---|---|---|
| 1 | 會跑出範圍 | 為了搞懂前因後果去讀別人家的程式,然後把別人的問題報成這次的發現 |
| 2 | 會被註解說服 | 有一次八個檔案查完零發現,但其中一支真的有洞——因為程式旁邊的註解寫著「這是故意這樣設計的」,AI 讀到就信了。沒找到不等於乾淨 |
| 3 | 投票可能整個沒跑成,而工具會記成「零發現」 | 看起來像「很乾淨」,其實是「根本沒查」 |
| 4 | 報出來的都是真的,沒報的不保證沒有 | 它標準嚴,寧可漏掉也不亂報 |
AI 被自己的「超時保護」誤殺
看到的現象:負責找問題的 AI 讀著讀著就被中斷、什麼都沒產出,一再重來一再失敗。
真正的原因(2026-09-20 查明):AI 讀太多東西的時候,系統會自動幫它「整理記憶」,整理要花兩三分鐘、期間完全沒有動靜;而工具的保護機制規定「三分鐘沒動靜就當它卡死、砍掉重來」。
所以死掉的不是 AI 想太久,是被自己的保護機制誤判成當機。
這是工具官方已知的錯誤,別人比我們更早踩到並回報:
Workflow stall watchdog kills agents during auto-compaction(anthropics/claude-code 問題編號 92424,2026-09-06 提出)
回報的人拿出了很完整的證據:他分析了 751 份執行紀錄,其中 33 次是這樣死的——每一次都是「最後一筆動作之後 180 秒整被中斷,中間完全沒有輸出」。他也量出整理記憶實際要花多久:一半的情況 156 秒,最慢 205 秒——而保護機制的容忍上限正好是 180 秒。
截至 2026-09-20,這個問題仍然是開啟狀態:沒有人認領、沒有官方回覆、也沒有任何修復。而且沒有任何設定可以避開——回報者試過調整觸發時機,但「180 秒」跟「重試六次」這兩個數字都不給改。
代價有多大:其中一次,同一個範圍打了 17 小時、重試 25 次、一個結果都沒有才喊停。回頭看那 25 次紀錄,有 22 次只寫了開頭一句話就被砍掉。
我們怎麼因應:每批再壓小、優先挑單一大檔而不是分散在多個檔案、跑大批的時候不同時跑別的、看失敗紀錄而不是看畫面,第二次失敗就停手,不讓它一直重試。
兩個數字說明問題:
3 次AI 報「沒發現問題」,實際都有真問題
約一半一開始的懷疑,後來證實是誤會
第一個數字:有三次 AI 正式回報「零問題」,但那三次其實都有真的問題,全部是人自己查出來的,包括證據最扎實的那一條(直接去資料庫撈出來證明)。
「工具沒查到問題」絕對不能當成「這裡是乾淨的」。
第二個數字:一開始列的懷疑,大約有一半後來被推翻。這是健康的。
被推翻的原因分別是:那段程式根本沒人在用、邏輯走不到那個分支、執行順序剛好擋住了攻擊路線。
為什麼「查清楚是什麼擋住了」跟「找到一個漏洞」一樣有價值
因為擋住它的如果是巧合,那哪天有人整理程式碼把那個巧合改掉,漏洞就自己回來了——而且沒有人會發現。
所以報告裡不只寫「這條不成立」,還要寫「是什麼東西擋住了它」。
兩個具體例子:
有一類問題工具特別不擅長:「一份刻意做壞的檔案,會不會讓系統卡住或記憶體爆掉」。工具讀程式碼只能估「這裡大概會慢」,估不出「慢到什麼程度、要多大的檔」。
所以合規文件核心與稽核輪次那幾輪,工具一條都沒提的時候,執行者自己動手做惡意檔案實際去打,量時間與記憶體:
| 哪一輪 | 做了什麼 | 量到什麼 |
|---|---|---|
| CMMC 官方 PDF 解析器 | 手做 7 種惡意 PDF(上千到兩萬頁、壓縮炸彈、單行幾萬字),另拿正常 PDF 亂數變造 3,000 次看錯誤訊息 | 兩萬頁吃掉 3.4GB;五頁、每行四萬字跑 52 秒;連修法都實測對照(每頁讀完就關,記憶體 534→128MB) |
| 主系統的 Word 內容抽取器與格式轉換器 | 範圍內每一條比對規則拿攻擊字串逐條實跑,另手做惡意 Word | 3,200 個空白 66 秒、三千個空段落 96 秒、一億欄的表格跑六分鐘未停 |
| 稽核計畫 Word、稽核結果 Excel 匯入 | 手做壓縮炸彈與「最後一列很遠」的 Excel | 4.9KB 的檔在第 20 萬列填一格,10.9 秒、355MB |
這幾輪「找到的存在嗎」可信度反而比投票還高——因為是量出來的數字,不是推論。但也要老實講打折處:多數沒有用客戶真實檔案跑完整流程,少數數字是從實測結果往上推算的(報告裡都標了)。
這一輪最常見的問題形狀,是有人把一條路守得很仔細、另一條路整個沒守——而守得仔細的那一半,正好證明開發者知道該守。工具很難看出這種問題,因為每一行程式都沒寫錯,是「本來應該有但沒有」。我們一共看到八種長相:
| 長相 | 白話說明 |
|---|---|
| ① 同一支程式隔幾行,一守一不守 | 改「分享設定」那條路有檢查歸屬,改「內容」那條路沒有 |
| ② 兄弟入口,一個掛一個沒掛 | 做同一件事的兩個功能,一個有權限檢查、一個沒有 |
| ③ 同一支檔案,寫入都守、讀取漏掉 | 新增、修改、刪除都要權限,唯獨「看」不用 |
| ④ 從別處複製過來,只補了寫那一半 | 程式從另一處複製改寫,補權限時只補了寫入,讀取整排沒補 |
| ⑤ 好幾個入口,只查過其中一個 | 三個匯出入口,當初只確認過一個 |
| ⑥ 好幾支方法,只有一支真的漏 | 六支都看起來一樣,其中一支少了那一行 |
| ⑦ 同一件事兩個入口、兩套門 | 畫面上一條條改要「修改」權限,走匯入整批覆蓋只要「建立」權限 |
| ⑧ 檢查甲、動手改乙 | 檢查的是網址上那個編號,真正動手改的是使用者另外送上來的編號 |
所以驗收補權限,不能數「有幾支掛了守門」
曾經有一塊被判定「守門看起來完整、不必單獨查」——理由是 25 個入口有 15 個掛了權限檢查。單獨查下去,八輪各找到一種漏法。要看的是「掛的那道問的問題對不對」,而且每個入口的檔名與行號要逐一列成驗收項,讀與寫分開數。
這是過程中訂下的一條規矩,值得寫進來。
起因是有一份報告,把工具跑了多久、派了幾個 AI 放在最前面,要往下捲到第 150 行才看得到第一個問題。當時的評語是「連工程師都不想看」。
於是訂了規矩:
① 這是什麼問題 ② 出事會怎樣 ③ 壞人要先有什麼才做得到 ④ 在哪裡 ⑤ 怎麼修
結論 → 查了什麼 → 總覽 → 細節 → 可信度 → 工具跑了多久放最後
還有一張對照表,規定技術詞要怎麼講。例如「TLS 憑證驗證被停用」要改寫成「連線的時候沒有確認對方是不是真的那個網站」。
「還沒查的」和「查過確認沒事的」,意思完全不同。
前者是不知道,後者才是確認安全。這一節把兩者分清楚——有人問起的時候,我們要答得出來。
| 情況 | 白話說明 |
|---|---|
| ① 從頭到尾沒排進來的面向 | 例如:存進資料庫的內容在畫面上怎麼顯示(那要查前端,兩次都沒查);防竄改機制的發證端、加密邏輯本身、出貨打包的流程 |
| ② 查證資源被「重複的舊問題」吃光 | 最誇張的一次:12 個疑點裡有 9 個是以前報過的,36 張票裡 27 張投在不該查的地方,真正投在該查的東西上只有 3 張——而那次真正重要的兩個問題,都是人自己找出來的 |
| ③ 沒有留下「每個檔案都看完了」的紀錄 | 最常見的一種。我們能說的是「這幾條問題確實存在」,不能說「這些檔案只有這幾條問題」 |
| ④ 現在沒事是靠運氣,不是靠設計 | 例如某個漏洞現在打不到,是因為程式的執行順序剛好擋住了——哪天有人整理程式碼把那個順序改掉,漏洞就回來了 |
| ⑤ 盤點本身就有死角 | 檢查「客戶資料有沒有隔開」的時候,只查了有記錄「這是哪個客戶的」那些資料表;連這個記錄都沒有的表,根本不在清單上 |
一、有一塊功能只能說「查了最關鍵的部分」
任務與成員管理那一塊,原本規劃七次、實際做了三次就停。剩下約 86 個檔案如果有別種類型的問題,這次不會被發現。
停下來是主動的取捨:同一個根本原因已經第三次出現,同樣的時間拿去查從來沒碰過的地方更有價值。
二、主系統自己的程式最後才查,有四條沒經過三票覆核
2026-09-20 曾經止損(檢視工具不可靠、繼續投入不划算),當時三塊完全沒碰;2026-09-21 決策者裁定重啟,換了上面講的兩個做法(跨兩個程式庫配對切、零發現輪靠實測)之後,那三塊與各模組的主系統接線在四天內查完。
主系統自己寫的那一層(826 個正式程式檔裡有判斷邏輯的 119 個,加上組裝設定)在 09-25~26 用 14 輪查完(見主系統自己的程式)。其中四條是執行者自己開檔找到、沒經過三票覆核,另有一輪工具一個疑點都沒提出——那幾處的可信度靠執行者逐支通讀與實測,只能說「查出的這些確實存在」。
| 你想知道 | 看哪裡 |
|---|---|
| 整體結論、該先做什麼 | 總報告首頁 |
| 某一塊功能查了什麼、結果如何 | 〈逐項檢視結果〉 |
| 所有問題按嚴重程度排下來 | 〈問題總表〉 |