Guidant AI 資安檢視 · 跨模組專項
這不是一個模組,是一次「同一塊功能整組搬家之後、回頭把有變動的部分重查一遍」的專項。它找到的新問題只有兩條(連同人工另查出的一條共三條,修法方向現已全部裁定),真正的價值在另一件事:回歸確認先前開出的四張工單,一張都沒有被修。
先說明這一頁跟其他模組頁不一樣的地方
其他頁講的是「某一塊功能第一次被檢視的結果」。這一頁講的是一次重查——意見回饋這塊功能原本一半放在主程式、一半放在共用模組,後來整組搬進共用模組裡,樣子變了,所以把有變動的那 93 個檔案重查一遍。
因為是重查,它的產出形狀跟第一次檢視不一樣:找到的新東西少(工具淨新增兩條,加上人工另查出的一條,下面表裡一共三條),但它回答了兩個第一次檢視答不了的問題——舊結論還算不算數、以及我們的方法重跑一次會不會給出一樣的答案。
使用者在系統裡遇到問題,可以按「意見回饋」回報:寫標題、寫描述、貼附件、選分類標籤。回報進來之後,管理員可以看清單、改、刪、匯出成 Excel,也可以把它轉成外部的問題單系統(GitLab 或 GitHub)交給開發處理。
為什麼要重查:這塊功能原本一半在主程式、一半在共用模組,後來整組搬進共用模組——新增 38 個檔案、刪掉 18 個、改了 25 個。第一次檢視(2026-09-10)看的是搬家前的版本,搬完之後那些結論還在不在原地,需要確認。
沒有變動的 57 個檔案沿用第一次的結論、不重查——重查只會多燒一輪,換不到新資訊。
檢視期間:2026-09-16(三輪同日)|範圍:93 個有變動的檔案(新增 38、改動 25、骨架與資料庫腳本 30)|共 3 輪
原始技術報告放在需求中心的 FR-101 站,檔名見下表最後一欄。那裡有每一輪的完整技術細節、檔案清單與逐條推理,供需要深究或稽核抽查時查閱。
| 輪次 | 查什麼 | 檔數 | 覆核投票 | 結果 | 原始報告檔名 |
|---|---|---|---|---|---|
| J1 | 意見回饋的完整路徑+對外的七支功能入口與守門殼 | 31 | 12 票全投完,四條全部三票一致,零漏投零中斷 | 通過 4 條全中等,去重後淨新增 1 條;另人工查出 1 條 | scan-J1-feedback-chain |
| J2 | 模組骨架、分類標籤、隨模組帶的資料庫腳本、共用元件 | 37 | 12 票全投完 | ⚠️ 工具在指定的 37 個檔裡一條都沒報(它報的 4 條全跑到別輪範圍)。產出全部來自人工查證:查出 1 條新問題、更正 1 條先前的誤判 | scan-J2-plugin-label-migration |
| J3 | 有改動的外部問題單整合與附件處理(回歸確認) | 25 | 18 票全投完 | 淨新增 0 條。價值在回歸確認(見下) | scan-J3-integration-regression |
第二輪(J2)必須誠實講:那 37 個檔案不能算「查過而且乾淨」
工具對這 37 個檔案零產出——它報的四條全部跑到別輪的範圍去了,而且跟第一輪報的那四條連檔名行號都一模一樣。
所以這一輪的結論不是工具給的,是人工給的:執行者照工作單列的六個重點逐項開檔查證、並連開發環境實查資料庫,才查出那條新問題與那條誤判更正。
要不要重跑一輪?統籌者判斷不重跑——這 37 個檔是骨架、分類字典、資料庫腳本與介面定義,六個重點已經涵蓋它的全部可被攻擊的面;再跑一輪覆核換不到新東西。但結論只能寫成「六個重點查過」,不能寫成「這 37 個檔乾淨」。
第三輪(J3)的覆核章標示為「未確認完整」,原因要講清楚
有一條疑點指向的是版本紀錄裡的一個歷史檔案(現在的程式樹裡已經沒有那個檔),報告產生器認為「檔案不存在」而把它退件,覆核章因此沒蓋成「完整」。
但覆核本身是完整跑完的——18 票全投完、四條通過都經三位一致確認。這是第三種情況,不算失敗。如實記錄。
這不是新漏洞,是一個關於執行狀況的事實。 第一次檢視開出的四張工單,重查時逐條開檔確認——
| 舊工單 | 當初查到什麼 | 重查結果 |
|---|---|---|
| CM-1630 | 意見回饋的七個操作裡只有「匯出」檢查權限,其餘六個任何登入帳號都能用;改別人的、刪別人的也從不檢查是不是自己的 | ❌ 照舊(搬家之後換了位置,問題原封不動) |
| CM-1632 | 連線 GitHub 時把憑證驗證關掉(兩處) | ❌ 兩處都還在(行號位移了而已) |
| CM-1633 | 刪除附件時的安全檢查只做了一半(算出了該過濾掉哪些,卻沒有真的用那個結果) | ❌ 一行未改 |
| CM-1607 | 版本紀錄裡殘留的舊密碼與金鑰 | ❌ 仍然撈得出來 |
本報告撰寫時再次逐條開檔核對,四條全部仍在原地。
這已經是第三次確認——第一次檢視查出、這次重查回頭核對、本報告撰寫時再逐條開檔看過一遍。把〈意見回饋〉那一頁最早開出的六張工單一併算進來,六條也全部仍在原地,一條都沒被修掉。(那一頁後來新增了第七條,是本次內化才查出來的,不在這次回歸確認的範圍內。)
這件事對決策者的意義
這四張工單不是被遺漏——它們是決策者裁定「等收集完所有檢視結果,再一起統一安排」的結果。制度上沒有問題。
真正要看的是另一面:這塊功能在這段期間經歷了一次大搬家(新增 38 個檔、刪 18 個、改 25 個),有人把整塊程式碼從頭到尾動過一遍——在那個過程中,這四件已知的事一件都沒有被順手修掉。
已知的問題不會因為程式碼被重新整理過就消失。 要修就得明確地排進去做。
排序按當初登記的順序。「出事會怎樣」那欄講的是業務影響——誰受影響、損失什麼,不是技術現象。
(第 2 條原本登記為中風險,這次調降為低。理由不是「影響變小了」,而是它的性質變了:查證後確認現在沒有任何地方會呼叫它、三個環境的那張表也都是 0 筆,而且已經裁定整塊移除——它是一塊要刪掉的死程式,不是一條等著修的外洩漏洞。維持中風險會讓讀者以為還有東西在漏。編號保持不動,才不會跟先前發出去的版本以及〈意見回饋〉那一頁的互相引用對不起來。)
| # | 問題 | 風險 | 分類 | 出事會怎樣(誰受影響) | 怎麼修 | 狀態 |
|---|---|---|---|---|---|---|
| 1 | 匯出的意見回饋檔案沒有過濾公式字元,可以被種公式炸彈 | 🟡 中 | 外部送什麼就收什麼 | 任何能送意見回饋的人(門檻只有登入),送一則標題以等號開頭的回饋;管理員匯出後用試算表軟體打開,那段內容會被當成公式執行——可以把同一份檔案裡其他欄位的內容送到外部網址,或在使用者點過安全性提示後執行外部程式。受害的是有匯出權限的管理員本人的電腦 | 匯出時把使用者可控的四個欄位(標題、描述、標籤名、建立者暱稱)先中和掉開頭的特殊字元。與另一處同樣的問題建議抽一支共用函式一起修。實際做法:意見回饋 csv/excel 兩個匯出分支都套了公式中和 | ✅ 已修(CM-2055) |
| 2 | 任何登入帳號都拿得到全站使用者名冊(含電子郵件)——查證後發現這其實是一塊沒有任何地方在用的死程式 | ⚪ 低 | 客戶資料沒隔開 | 不必是管理員,任何一個登入帳號送一個空白查詢,就把整張成員名冊撈回來——那張表連「這是哪家客戶的」欄位都沒有、也沒有任何隔離規則。不過查證後確認:現在沒有任何地方會去呼叫它,三個環境的那張表也都是 0 筆。真正的問題不是它現在在漏,而是它是一個沒人看管、隨時可能被接上去的入口 | ✅ 已裁定:整塊移除(入口、資料表、同步程式一起拿掉),不補隔離、不留著。已實作:只拿掉對外查詢入口,資料表與同步程式保留,因為「意見回饋」指派負責人功能內部還在呼叫它們 | 🗑️ 已裁定刪除,已刪除(FR-114.3-4,1.21.0 出貨) |
| 3 | 沒有被分配部門的一般使用者,送意見回饋會失敗、而且畫面看不出原因 | 🟡 中 | 要先做產品決策 | 這不是資安漏洞,是一個完全靜默的功能故障:管理員去查這個人的權限,每一項都對,就是送不出去,畫面也不給任何理由。新客戶剛裝好、部門還沒建起來的時候特別容易踩到 | ✅ 已裁定:放寬那條資料庫規則——送意見回饋跟你在哪個部門本來就無關。已修:那條「新增」規則改成跟另外三條一模一樣(超級管理員可略過,否則看是哪一家客戶),把「必須有部門」整個拿掉。客戶歸屬照舊擋得住——已實測:沒有部門的人送得出去而且客戶欄位正確記錄,但跨客戶送、客戶欄位留空這兩種仍然被擋,隔離沒有跟著鬆掉 | ✅ 已修(FR-114.1-9) |
這四條不是這次新找到的,列在這裡是因為這次逐條回頭確認過它們還在原地。詳細歸在〈意見回饋〉那一塊的報告。
| 問題 | 風險 | 狀態 |
|---|---|---|
| 七個意見回饋操作只有「匯出」檢查權限;改刪別人的也不檢查是不是本人 | 🟡 中 | ⬜ 未修(工單 CM-1630) |
| 連線 GitHub 時關掉憑證驗證(兩處) | 🟡 中 | ⬜ 未修(工單 CM-1632) |
| 刪除附件的安全檢查只做一半 | ⚪ 低 | ⬜ 未修(工單 CM-1633) |
| 版本紀錄裡殘留的舊密碼與金鑰 | 衛生性清理 | ⬜ 未修(工單 CM-1607) |
裁定:照日誌那塊已經定下的全站原則做——「中和」不是「刪除」,資訊一個位元都不能少。做法是與日誌那塊第 2 條抽一支共用的中和函式,兩處一起修。
為什麼不能用刪字元的做法:日誌本來就有不可竄改的要求,為了讓試算表安全就把使用者原本寫的字刪掉,說不過去——被竄改的是現況、不是修法。
這條直接套用已經定下的原則,不需要重新討論。
先把分界講清楚——這塊有兩件事,只拿掉第二件:
| 現況與裁定 | |
|---|---|
| ① 把意見回饋寫成 GitLab/GitHub 的問題單 | ✅ 在用、正常運作,完全不動 |
| ② 開單時「指派給誰」的那份成員清單 | ❌ 拿掉 |
決策者裁定:拿掉,不補隔離、不留著。
理由(這是產品判斷,比技術理由更重要):兩邊不會有一樣的人。 我們系統裡的使用者,跟 GitLab/GitHub 上的開發人員本來就是不同的一群人;單子開過去之後,由那邊的人自己去指派維修,跟我們無關。 所以這不是「先擱著、以後再補隔離」,是判定這個功能根本不該存在。未來若真的需要,另外當成新需求來做。
查證依據——它本來就是死的:
要拿掉的範圍:那支入口(刪掉掛載,同時要改那份網址凍結清單——有測試盯著那條網址不許消失,漏改會紅)/成員表與相關的資料存取程式/那支把成員同步進來的程式。三個環境都 0 筆,沒有資料需要處理。
🔴 所以這條的性質變了:原本登記的是一條「任何登入者都撈得到全站名冊、含電子郵件」的資料外洩問題,現在它是一塊該刪的死程式——處理方式從「補隔離」變成「整塊移除」。
風險等級也因此由中調降為低(決策者裁定)。判準是「現在打得到嗎、未來會不會打到」——兩個都是否:三個環境 0 筆、沒有任何地方在呼叫它,而且已經裁定整塊移除。降級的理由是「已裁定整塊移除、不是待修的漏洞」,不是「影響變小」。 同樣形狀的另外兩條(稽核流程那塊的第 14、16 條)在那一頁也不放在資安問題表裡,而是列在「不是資安問題、但確實是程式錯誤」那一區——三處形狀一致,等級也該一致。
這條與稽核流程那塊的兩條是同一個形狀
稽核流程那塊有兩條:一支沒人呼叫但會接收檔案路徑的程式、一個接好了但沒人用、而且完全沒有任何權限檢查的備用服務。它們與這條的共通點是:
現在無害的唯一理由是「沒人用它」。只要哪天有人把它接上去,就憑空多出一組沒有檢查的入口。
那兩條的裁定同樣是直接刪掉。收尾章節會把這三處歸成同一組處理。
裁定:選「放寬那條資料庫規則」。
| 選項 | 裁定 |
|---|---|
| 放寬那條資料庫規則 | ✅ 採用——送意見回饋跟你在哪個部門本來就無關,那條規則從一開始就不該要求部門 |
| 規定帳號一定要有部門 | ❌ 不採用——會影響所有既有帳號與建帳流程,為一個邊界情況去改必填規則,代價不成比例 |
| 只把錯誤訊息講清楚 | ❌ 不採用——只是讓使用者知道自己卡住了,沒有解決卡住這件事 |
🔴 成因已經查明:那張新的回饋資料表有四條隔離規則,其中只有「新增」那一條沒有給超級管理員留旁路,而且它是唯一要求使用者必須有部門的。這正是「權限查起來每一項都對、就是送不出去、畫面也不給理由」的來源。
🔴 施工時要一併確認:放寬之後,沒有部門的人送出來的回饋,客戶歸屬仍然要正確記錄下來——部門欄位留空可以接受,但客戶不能空。
第三輪是全案第一次有機會驗這件事:同一批程式、間隔六天、重跑一次完整流程。
結果是高度一致——連嚴重程度的判定與建議修法都幾乎逐字相同。這對「我們的方法穩不穩定」是好消息。
但它同時說明另一件事:重查挖不出新東西。 要提高涵蓋面,得換方法,不是重跑。
刪除附件那條(CM-1633)就是例子:程式算出了「該過濾掉哪些檔案」,接下來卻用回了沒過濾的那份清單。這是明確的程式錯誤。
但自動工具兩次都沒有報它。原因是查核程序的推論停在一個問題上:「現在打得到嗎?」——答案是打不到(目前的操作流程一次只會傳一個檔案編號),所以判定不成立。
這是一個要記住的盲點
「程式寫錯了」與「現在有人打得進來嗎」是兩件事。 我們的方法擅長回答後者,前者要靠人開檔看。
這條的實際後果是:未來如果做了批次刪除功能,可能會在使用者不知情的情況下刪錯檔案——現在不痛,將來會痛。
先前登記「意見回饋有六張資料表完全沒有客戶隔離」。這次查證後剔除了其中一張——分類標籤那張表是全站共用的下拉選項字典(就像「縣市」「職稱」那種對照表),整張表沒有任何「這筆屬於誰」的欄位,全部回傳本來就是正確行為,不是缺口。
六張改成五張。 剩下五張(問題單、成員,加三張關聯表)在資料庫層確實仍然零隔離——本報告撰寫時連開發環境唯讀實查,隔離開關都是關的、規則 0 條、也都沒有客戶歸屬欄位。
但「沒有隔離」不等於「會外流」:本報告撰寫時逐支入口核對,這五張裡只有成員名冊那一張有直接入口打得到(就是上面第 2 條那條,已裁定連同入口一起移除);另外四張(問題單與三張關聯表)四條意見回饋入口全部先查受隔離保護的回饋主檔,拿到本客戶的回饋之後才去取對應內容,沒有一條能從外面直接指定要哪一筆。完整的三分類見〈意見回饋〉那一頁的資料表那一節。
一句話:這次重查只找到兩條新問題(連同人工另查出的一條共三條),但它證實的那件事比新問題重要——第一次檢視開出的四張工單,經過一次大規模的程式重整,一張都沒有被修。
三條新問題的修法方向都已經裁定,剩下的是排工。
建議:
| 統計 | |
|---|---|
| 檢視輪數 | 3 輪、93 個有變動的檔案(另 57 個無變動的沿用第一次結論) |
| 通過的發現 | 14 條(去重後淨新增 2 條,其餘為第一次檢視已登記項的重複) |
| 最嚴重 | 0 條 |
| 高風險 | 0 條 |
| 已修 | 2 條(第 1、3 條,1.21.0 出貨) |
| 裁定刪除,已刪除 | 1 條(第 2 條,1.21.0 出貨) |
| 回歸確認的舊工單 | 4 張(CM-1630/1632/1633/1607,狀態見意見回饋與寄信與通知兩頁) |