Guidant AI 資安檢視 · 模組報告

意見回饋(jedi-issue)

使用者按「意見回饋」回報問題,系統可以把它同時開成 GitLab/GitHub 上的一張真問題單。七個操作裡只有「匯出」做了權限檢查,另外六個任何登入帳號都能用。這一塊另外撞出全案最廣的一次密碼外流:資料庫密碼散在 249 個檔案裡。

先說明這一頁的時間點

這一頁講的是第一次檢視(2026-09-09~10)的結果。之後這塊功能整組搬過家(原本一半在主程式、一半在模組裡,後來全部搬進模組),有變動的部分另外重查過一次——那次重查的結果在〈意見回饋重新檢視〉。

兩頁要一起看:這一頁是「當時查到什麼」,那一頁回答「搬家之後還在不在」(答案是:都還在)。

§1

這塊在產品裡做什麼

使用者在系統裡遇到問題,可以按「意見回饋」回報:寫標題、寫描述、貼附件、選分類標籤。

回報進來之後,管理員可以看清單、改內容、刪掉、匯出成 Excel 或 CSV。另外還有一條路——系統可以拿公司的通行證去 GitLab 或 GitHub 開一張真正的問題單,把使用者填的字與上傳的檔案一起送過去;回饋被刪掉時,那張外部問題單也會跟著被關掉。


§2

檢視軌跡

檢視期間:2026-09-09 ~ 2026-09-10,另 2026-09-23 補一輪|範圍:158 個檔案(模組本體 127、接線 31);另加主系統接線一輪(與設備清冊並排查,共 8 個檔)|共 7 輪

原始技術報告放在需求中心的 FR-081 站,檔名見下表最後一欄。那裡有每一輪的完整技術細節、檔案清單與逐條推理,供需要深究或稽核抽查時查閱。

輪次 查什麼 檔數 覆核投票 結果 原始報告檔名
I1 怎麼連去外部問題單系統、通行證怎麼帶 25 9 票全投完 找到 2 條 scan-I1-third-party-integration
I2 我們主系統這端怎麼把它接上來 31 30 票全投完 找到 5 條,含這一塊唯一的高風險 scan-I2-host-wiring
I3 附件的上傳與下載 14 9 票全投完 工具零發現+人工另查出 1 條 scan-I3-attachments
I4 對外介面與模組的掛載契約 20 12 票全投完 工具零發現(兩項查證由統籌者補做) scan-I4-plugin-contract
I5 業務邏輯層 40 15 票全投完 找到 1 條(連內部套件庫走沒加密的連線) scan-I5-app-domain
I6 資料怎麼存、怎麼取 28 9 票全投完 工具零發現+統籌者查出多張資料表完全沒有客戶隔離 scan-I6-persistence
W6(主系統接線,與另一塊並排查) 我們主系統這一端怎麼把設備清冊與意見回饋兩塊接上來 8 6 票全投完 沒有找到新問題——自動檢視報的兩條都是已登記的舊帳;執行者另查出一件「修好的模組還沒發版」(不是新問題,已記在修正排程裡)。意見回饋這一半的接線範圍內,這一輪沒有新發現 scan-W6(在 FR-115 站)

六輪覆核全部完整跑完、零漏投、零中斷——這是全案第一次

三位覆核員一共投了 84 票,沒有一條漏投、沒有一輪中途被截斷。這一批是目前唯一做到「每條發現都投完票」的。

(要注意的是:完整不等於乾淨。有三輪工具零產出,真正的發現是人工查出來的,見下。)

開工前就先抓到一個錯誤的前提,值得記一筆

模組的說明文字白紙黑字寫著「GitLab/GitHub 整合目前產品沒有在用,大約佔這個模組的 58%」。

統籌者從主系統那一端查證,這句話是錯的——主系統裡有六處實際在呼叫那些功能,由兩個開關控制。

為什麼這件事要緊:如果照那句話跳過那 58%,跳過的恰好是風險最高的那一半(對外連線+通行證)。說明文字會騙人,要看程式實際怎麼被呼叫。


§3

問題一覽

排序按風險,同風險的同一類排在一起。「出事會怎樣」那欄講的是業務影響——誰受影響、損失什麼,不是技術現象。

# 問題 風險 分類 出事會怎樣(誰受影響) 怎麼修 狀態
1 資料庫管理員密碼散在 249 個檔案裡,其中一份把主機、帳號、密碼三行湊成一條可直接使用的連線指令 🟠 高 密碼外流 拿得到程式碼的人(含離職者、外包)可以直接連進資料庫。這個帳號可以繞過所有客戶隔離,每一家客戶的資料可讀可寫。而且同一組密碼同時通行四處:開發環境、出貨基線資料庫(客戶拿到的安裝檔就是從這座資料庫長出來的),以及兩座標示「已退役」但機器上還活著、拿這組密碼照樣連得進去的舊資料庫——等於兩個沒人在看的入口。這組密碼同時也是快取服務的密碼 三步、順序不能顛倒:先堵住再寫進去的路 → 清掉已經寫進去的 → 換密碼(換密碼要決策者明確指示) ✅ 已修(CM-2049)
2 七個意見回饋操作裡只有「匯出」檢查權限,其餘六個任何登入帳號都能用;改別人的、刪別人的也從不檢查是不是自己的。整個模組對外九支入口,八支只驗登入 🟡 中 只驗登入、不檢查歸屬 這是目前所有問題裡唯一一條「一般員工現在就能實際操作利用」的,不需要任何特殊權限。任何員工可以刪掉或竄改別人的回饋,連帶把外部問題單系統上的那張單子也一起關掉;而稽核紀錄還會把操作人記成合法本人 後端補上權限檢查(十顆權限資料庫裡都已定好,純接線)、再加上「這筆資料是不是你的」的檢查;清單分兩套邏輯(已裁定,見下)——已修:六個操作全部補上權限檢查(讀取那兩個收「管理」或「唯讀檢視」任一顆,唯讀檢視的角色才不會被擋在門外);改、刪、刪附件三個在動手前比對「這筆是不是你送的」,不是本人一律擋下,而刪除的比對放在關閉外部問題單之前——非本人時一次外部呼叫都不會送出。清單分兩套的做法照決策者裁定:不開第二支入口,改在現有清單入口加一個「查看範圍」參數(我的/全部),「全部」需要「唯讀檢視」那顆權限,不帶參數時依呼叫者的權限推定(行為與修改前一致,只有原本不該看到全部的人被收窄)。實查開發環境 14 個角色五顆權限全部都有,今天不會有任何人被擋 ✅ 已修(FR-114.1-7)(工單 CM-1630)
3 Google 雲端硬碟的應用程式密鑰與加密金鑰外流(散在 15 個檔案裡) 🟡 中 密碼外流 這組密鑰不是每套安裝各自產生的,而是 Google 後台唯一一組、所有客戶環境共用——一旦外流,影響範圍比其他金鑰外流都大。配合第 1 條拿到資料庫之後,可以解密所有客戶存的雲端硬碟通行證、讀取客戶檔案 到 Google 後台重設應用程式密鑰;加密金鑰要每個環境一把、不要共用,而且換之前要先寫好「把既有通行證重新加密」的程式 ✅ 已修(CM-2051)
4 連線到 GitHub 時把憑證驗證關掉(兩處) 🟡 中 密碼外流 帶著公司的 GitHub 通行證走一條不確認對方是不是真的 GitHub 的連線——網路上的中間人可以假冒 GitHub,把公司的通行證攔走。這個模組的通行證外流過一次(已處置),現在同一個模組還在用這種方式傳它 把那兩處的關閉開關拿掉。實際做法:拿掉兩處 Github client 的 verify=False,恢復預設憑證驗證 ✅ 已修(CM-2066)
5 連公司內部套件倉庫走的是沒有加密的連線,而且這是安裝套件的主要來源(28 支程式庫全部一樣) 🟡 中 密碼外流 內部網路裡有心人可以在安裝套件的當下偷偷掉包內容,等於在打包機上執行他的程式碼——而打包機產出的就是客戶實際拿到的安裝檔。這是整條供應鏈最根本的一個破口 內部套件倉庫改走加密連線;順便把鎖定套件版本的那份檔案納入版本控制(第二道防線目前也沒跟著出貨) ⬜ 未修(工單 CM-1634)
6 打包前端映像檔的那支腳本裡直接寫著一組帳號密碼,而那支腳本本身就進了版本控制(跨兩個程式碼倉庫、至少四個檔) 🟡 中 密碼外流 與第 1 條同一個形狀——憑證寫進版本控制,任何拿得到程式碼的人(含離職者、外包)都拿得到它,刪掉檔案也沒用。拿到的是內部套件倉庫的帳號,而那個倉庫是所有套件的來源——等於拿到往打包流程裡塞東西的位置,而打包出來的就是客戶安裝的檔案 把帳密移出版本控制,改從環境變數或設定檔讀。⚠️ 要先去後台確認那個帳號到底是不是唯讀——腳本裡註解說它是唯讀所以「非機密」,但帳號名是管理員層級,這句話要實際查過才算數;若不是唯讀,嚴重度要上調並且要換密碼 📋 已裁記錄不修(1.21.0)(工單 CM-1998)
7 刪除附件時的安全檢查只做了一半(算出了該過濾掉哪些,卻沒有真的用那個結果) ⚪ 低 外部送什麼就收什麼 目前打不到——現在的操作流程一次只會傳一個檔案編號。但未來如果做批次刪除功能,會在使用者不知情的情況下刪錯檔案,而且不會報錯 把算出來的過濾結果真的拿去用(一行)。實際做法:delete_attachment 刪檔案時改用已算好的 matched_file_uids(過濾後結果) ✅ 已修(CM-2066)

這塊另外查到的資料表隔離狀況

這條不是工具查到的,是統籌者補查出來的,屬於設計層級的註記而非立即可利用的漏洞。原本登記為「六張表完全沒有客戶隔離」,逐支入口核對後收斂成下面這個樣子。

這塊的資料表在資料庫層確實都沒有開客戶隔離、也沒有「這是哪家客戶的」標記欄位。但「沒有隔離」不等於「會外流」——判準只有一個:有沒有一支入口可以直接查這張表? 有就必須處理;沒有、只能從已經受隔離的主檔連過來,那就靠主檔那道規則就好,在下游再做一次反而變成兩套真相、日後兩邊會各自漂移。

照這個判準,原本登記的那批表分成三類:

類別 哪幾張 實際狀況
A 有直接入口|唯一要處理的 成員名冊(1 張) 那支入口只要登入就打得到,底層是整張表倒出來——沒有任何條件、也沒有參數可以篩,內容含電子郵件。(查證後確認:現在沒有任何地方在呼叫它、三個環境的表也都是 0 筆,所以它是一塊該刪的死程式,裁定整塊移除)
B 靠主檔擋|不用重複做 問題單、標籤對應、指派對應、附件對應(4 張) 四條意見回饋入口全部先查受隔離保護的回饋主檔,拿到本客戶的回饋之後才去取對應內容,沒有一條能讓外面直接指定要哪一筆。(指派對應那張另註:往它寫資料的功能根本沒有對外入口,實質是死功能。)
C 不是缺口 標籤字典(1 張) 內容是系統預設的回饋類型與功能選單,由安裝腳本建立,沒有任何入口能讓客戶自己新增標籤——它不是客戶資料,全部回傳本來就是正確行為

🔴 所以六張裡只有成員名冊那一張需要處理,而處理方式已經裁定是「連同那支入口整塊移除」——不是「待補隔離」。詳見〈意見回饋重新檢視〉第 2 條。

六張改成五張的更正(標籤字典那張本來就不是缺口)也記在那一頁。

本報告撰寫時連開發環境唯讀實查:這幾張表的隔離開關確實是關的、規則 0 條、也都沒有客戶歸屬欄位;對照之下,後來新建的那張回饋表有四條隔離規則、也有客戶欄位,差異非常明顯。

而且新表沒踩到「方向寫反」那個坑——它用的是有做路徑前綴比對的正規寫法,而且明確處理了「沒設定就一律拒絕」這種邊界情形。弱點檢測那塊被查出方向寫反的,是另一種「把路徑切成一段一段、再比編號大小」的寫法,兩者不同源。

順帶一個觀察(不影響結論):程式在組意見回饋清單時,是先把整張問題單表讀進記憶體、再用本客戶的回饋清單過濾。結果沒有外流,但這個寫法很脆——哪天有人為了效能改成「直接把讀進來的這批回出去」,防線就破了。


§4

第 1 條:一組密碼,249 個檔案

這是全案散布範圍最廣的一次密碼外流。

而且外流的那一組可以繞過所有客戶隔離——拿到它,每一家客戶的資料都可讀可寫。

問題是什麼

一組資料庫管理員密碼(同時也是快取服務的密碼),被寫進了 249 個進版本控制的檔案裡——大多是開發過程留下的對話紀錄、維運腳本、遷移計畫。

其中最麻煩的一份,把主機位址、帳號、密碼三行湊在一起,等於一條可以直接複製貼上使用的連線指令。

這組密碼現在通行四個地方:開發環境、出貨基線資料庫,以及兩座標示「已退役」、但機器上其實還活著、拿這組密碼照樣連得進去的舊資料庫。展示機已經在 2026-08-29 改成安裝版之後獨立出去,不再是同一組——但這件事沒有讓嚴重程度變低:

  • 出貨基線資料庫比展示機更要緊——客戶拿到的安裝檔,裡面那套資料庫結構與預設資料就是從這座資料庫長出來的。動得了它,等於動得了往後每一家客戶裝出來的系統。
  • 那兩座舊資料庫是沒人在看的入口。它們被當成退役的,所以不會有人注意到有誰連進去過。

本報告撰寫時重新數了一次,仍然是 249 個檔案。

為什麼這條評為高風險

判斷依據 這件事
這組帳號能做什麼 繞過所有客戶隔離,每一家客戶的資料可讀可寫
有幾個地方共用 四處——開發環境、出貨基線資料庫(安裝檔的來源),加上兩座「已退役但還連得進去」的舊資料庫
誰拿得到 任何接觸過程式碼的人,包含離職者與外包
刪掉檔案有用嗎 沒有,已經留在版本紀錄裡

怎麼修

三步,順序不能顛倒。

步驟 做什麼 為什麼不能省
一、先堵住再寫進去的路 改用作業系統原生的密碼檔存密碼,指令裡就不必打密碼;對話紀錄歸檔前先自動遮蓋;評估在提交前加自動掃描 不做這一步,清乾淨了還會再長出來
二、清掉已經寫進去的 249 個檔裡的密碼字串換成「請查設定檔」。那份有完整連線指令的優先處理 網頁版不用手改——它們是從文件產生的,改完文件重跑產生指令即可
三、換密碼 ⚠️ 換的時候要同步:設定檔、機器上的環境變數、快取服務設定、所有連線腳本。建議把快取服務與資料庫的密碼分開(目前是同一組)。順便把那兩座已退役的舊資料庫關掉或收回——留著只是多兩個沒人看的入口 ⚠️ 這一步要決策者明確指示——要動的是出貨基線資料庫與那兩座舊資料庫,屬環境異動

不重寫版本紀錄(決策者已裁定):重寫會改動所有提交編號、影響每個下載過程式碼的人,而對已經散出去的內容毫無補救效果。


§5

第 2 條:七個操作只守住一個

問題是什麼

意見回饋有七個操作。只有「匯出」掛了權限檢查。

操作 誰能做
新增回饋 任何登入帳號
看清單 任何登入帳號
看單筆明細 任何登入帳號
改別人的回饋 任何登入帳號,而且不檢查那筆是不是你的
刪別人的回饋 任何登入帳號,而且不檢查那筆是不是你的
刪除附件 任何登入帳號
匯出 ✅ 有檢查權限

再往外看一層,整塊還更寬:這個模組對外一共開了九支入口,其中八支只驗登入——除了上面那七個操作,另外兩支是:

  • 全站使用者名冊:登入就能撈,回來的是所有客戶的人(含電子郵件)。這一支就是〈意見回饋重新檢視〉第 2 條講的同一件事,兩頁指的是同一條入口;那一頁已裁定把它連同背後的成員表一起移除。
  • 標籤下拉清單:登入就能取,內容是系統預設的回饋分類選項(不是客戶資料,見上面資料表那節的 C 類)。

這兩支在原本的報告裡完全沒提到,這次補上。

本報告撰寫時開檔核對這些功能與背後的業務邏輯,改與刪那兩支從頭到尾沒有任何「這筆是不是你的」比對。

為什麼這條要緊

這是目前所有問題裡唯一一條「一般員工現在就能實際操作利用」的——不需要任何特殊權限,不需要任何技術手段,在正常的操作介面上就做得到。

而且它的影響會跨出我們的系統:刪掉一筆回饋時,系統會順手把外部問題單系統上的那張單子也關掉。等於任何員工都能關掉開發團隊正在處理的問題單。

更麻煩的是稽核紀錄會把操作人記成合法本人——事後追查時看不出異常。

怎麼修

兩層都要補,缺一不可。

層次 做什麼 注意
一、權限檢查 用現有的統一守門機制,不要另外寫一套 這一條不卡任何決策:十顆權限項目在資料庫裡全部已經定義好、也已經綁在前端選單上,缺的純粹是後端那一段接線
二、歸屬檢查 改或刪之前先確認那筆是不是自己的(或有沒有管理權限) 要放在業務邏輯那一層,因為要先把資料撈出來才知道要判誰

裁定一:後端要補上權限檢查(這是改裁,過程值得記一筆)

現況是:這塊宣告了十顆權限,後端真正在擋的只有五顆(整合設定四顆+匯出一顆),另外五顆(新增/讀取/修改/刪除/管理頁)只有前端選單在認——選單藏起來了,但把網址直接貼到瀏覽器一樣進得去。

決策者一度裁「不補」,理由是怕重演設備清冊那塊的狀況:那邊補了檢查之後,使用者看到的是一個空的下拉選單,不知道發生什麼事。

統籌者回頭查證,發現兩塊的形狀根本不同,那個理由在這裡不成立,決策者據此改裁「要補」。 三項查證全部是綠燈:

查什麼 結果
這些入口有沒有被別的頁面借去當資料來源? 沒有——只有意見回饋自己那兩支頁面在呼叫。設備清冊那塊是「一個讀取入口被四個不相干的頁面當資料來源」,形狀完全不同
補下去會不會擋掉現在的人? 不會——開發環境 14 個角色、41 個使用者,14 個角色五顆權限全部都有,零缺漏
新客戶裝起來會不會踩到? 不會——出貨的初始資料只建一個管理員角色,五顆全給,兩條選單路由也都掛好了

實際效果:把前端本來就在認的那套規則,在後端也認一次。今天不會有任何人被擋;等到哪天管理員真的去取消某個角色的勾選,那一格才會生效——而不是像現在,選單藏了、網址貼上去照樣能用。

裁定二:清單要分成兩套邏輯——但要修的是兩件事,不是一件

裁定結果:

  • 「我的意見回饋」那一頁:只回自己建立的回饋。
  • 管理頁:回整個客戶的(但要真的檢查呼叫的人有沒有管理權限)。

🔴 報告原本把這條寫成「補權限檢查」,漏掉了前面那件更基本的事:

後端目前分不出這兩頁是誰在呼叫。 前端確實有兩個路由、選單也各自綁了一顆權限,但兩頁用的是同一個畫面元件、打的是同一支功能入口——後端只看到「有人要清單」,就把整個客戶的回饋全部回傳。

所以順序是:

步驟 做什麼 為什麼不能省
一 先讓後端能分辨這兩種呼叫 沒有這一步,第二步做不到——後端根本不知道該套哪一套規則
二 兩邊各自套不同規則 自己那頁只回自己的;管理頁回整個客戶的,但先確認有管理權限

連帶一件:自己那頁只看得到自己的回饋,改與刪自然也只改得到自己的。但後端仍然要獨立檢查一次——「看不到所以改不到」是前端在擋,把網址直接貼上去就繞過去了。


§6

第 3~7 條:其餘五條

第 3 條:Google 雲端硬碟密鑰外流(中)

問題:應用程式密鑰、加密金鑰、應用程式編號,以及一把對外介接用的金鑰,一共散在 15 個檔案裡,全部集中在開發過程留下的對話紀錄裡、也全部進了版本控制。

⚠️ 這個數字修正過:原始報告寫 22,那是把分開記的「密鑰 12 檔」與「加密金鑰 10 檔」直接相加;但兩批檔案本來就有重疊,取聯集只有 13 檔,再把應用程式編號與那把對外介接金鑰算進去才是 15。

這組不是每套安裝各自產生的,而是 Google 後台唯一一組、所有客戶環境共用——這是它比其他金鑰外流更嚴重的原因。新的佐證:比對展示機上那把應用程式密鑰,與開發環境完全相同(只比對了雜湊值,沒有取出明文)。

修法:⚠️ 重設金鑰要決策者明確指示。 應用程式密鑰到 Google 後台重設,重設後檢查後台的授權紀錄有沒有異常活動;加密金鑰要每個環境一把、不要共用,而且換之前要先寫好「把既有通行證重新加密」的程式,否則客戶既有的雲端硬碟整合會全部失效。清理工作可以先做,不用等重設。

第 4 條:連 GitHub 時關掉憑證驗證(中)

問題:兩處程式碼在連線到 GitHub 時,關掉了「確認對方是不是真的 GitHub」這道檢查。帶過去的是公司的通行證。

本報告撰寫時開檔核對,兩處都還在。

前科:這個模組的通行證外流過一次(已處置)。現在同一個模組還在用這種方式傳它。

原始報告寫「這是同一種問題第四次出現」(另外三次是員工帳號目錄、快取服務、寄信),這次逐條重查,結論要改:

原本列的 重查實況
GitHub 兩處 ✅ 仍然成立,一行未改(GitLab 那一半沒有這個問題)
員工帳號目錄 ➖ 不再計入。已經改成客戶自己可以選的設定項,而且預設是有驗的;真的關掉時程式會寫一行警告說這只建議用在測試環境。性質從「寫死不驗」變成「可設定」
快取服務 ⚠️ 一邊修了、一邊沒修。共用模組那邊已經改成「只要開了加密就一定要驗、不給退回」,但主專案自己那支仍然寫著不驗——而且主專案有兩個地方在用它
寄信 ❌ 這條不成立。寄信程式用的那套語言內建元件,加密連線預設本來就不驗對方身分——那是語言層自己的行為,不是我們這支程式去把它關掉的。真要計入的話,說法得改成「語言預設不驗、我們沒有額外加強」——與「程式寫死關掉」不是同一件事

🔴 所以目前真正「程式寫死不驗」的是三處:GitHub 兩處,加上主專案的快取服務一處。 那個「共用模組修了、主專案自己那支漏掉」的形狀特別值得記——同一件事修一半,剩下那一半沒人再回頭看。

第 5 條:內部套件倉庫走沒加密的連線(中)

問題:連線到公司內部套件倉庫走的是沒有加密的連線,而且這是安裝套件的主要來源——28 支程式庫全部一樣(現役套件 21 支、已封存 6 支,加上主專案本身 1 支)。原始報告寫 26,那是 2026-09-09 當時的數量。

本報告撰寫時核對,主專案與模組的設定檔都還是這樣,一個都沒有改。

為什麼這是供應鏈最根本的破口:內部網路裡有心人可以在安裝套件的當下偷偷掉包內容,等於在打包機上執行他的程式碼——而打包機產出的就是客戶實際拿到的安裝檔。

同一條後來在另外兩塊獨立撞到過(共用地基那塊、稽核流程引擎那塊),證實這不是單一程式庫的疏漏,是全部程式庫都一樣。

🔴 這次另外查到一件事,已經獨立成下面的第 6 條:打包前端映像檔的那支腳本裡,除了明文網址之外還直接寫著一組帳號密碼。那是另一件事、修法也不一樣,所以不併在這一條裡(原因見第 6 條)。

連帶一件:鎖定套件版本的那份檔案(用途是「用雜湊比對確認套件沒被掉包」這第二道防線)——原始報告寫「被排除在版本控制外」,這次查證是一半對:

  • 共用模組那邊仍然沒有:27 支套件裡有 17 支本機產生了這個檔,但一支都沒有進版本控制,全被忽略規則擋掉了。
  • 主專案已經補上了,自 2026-08-15 起入版本控制。

第 6 條:打包腳本裡寫著帳號密碼,而腳本進了版本控制(中)

問題:我們打包前端程式、做出客戶要安裝的映像檔時會跑一支腳本。那支腳本為了去公司內部的套件倉庫抓東西,在程式碼裡直接寫死了一組帳號密碼。

密碼不是明文,是用一種看起來像亂碼、但任何人一行指令就能還原的編碼寫的。這不是加密,只是換個樣子寫——等於把鑰匙放在門口地墊下面。

本報告撰寫時開檔核對,而且往外查了一輪:

  • 這支腳本確實已經進版本控制。
  • 同一組帳密在前端那個程式碼倉庫的三個流程設定檔裡也有,同樣入版控——所以這是跨兩個程式碼倉庫、至少四個檔的事,不是只有一支腳本。
  • 解出來的帳號是管理員層級的名字,不是一個限定唯讀的專用帳號。
  • 這組密碼與第 1 條那組資料庫密碼不是同一組,是各自獨立的兩組。

為什麼要跟第 5 條分開(同一支腳本的相鄰兩行,但是兩件事):

第 5 條 第 6 條(這一條)
問題 連線沒有加密 憑證寫進版本控制
性質 傳輸過程可能被偷看、被掉包 東西已經流出去了,刪檔案也收不回
修法 把網址改成加密連線 把帳密移出版本控制

🔴 分開列的實際理由:兩者在腳本裡是上下相鄰的兩行。如果併成一條,去修「連線沒加密」的人很可能改完網址就收工,完全沒注意到下一行那組帳密還躺在那裡。

腳本裡那句「非機密」的註解,不能照單全收

腳本裡寫著這組帳密「非機密,是內網倉庫的唯讀憑證,前端倉庫裡本來就是明文」。

前半段是事實(前端倉庫確實也有,已經核對過)——但那不構成「非機密」的理由,它只說明同一個問題有四個檔。

「唯讀」這件事則還沒有人實際查過。 帳號名是管理員層級,要去後台看過才算數:

  • 若確實唯讀、而且只讀得到公開代理的內容 → 風險確實低,但仍應移出版本控制,並把那句註解改成準確的說法。
  • 若不是唯讀、或讀得到內部套件 → 嚴重程度要往上調,而且要換密碼。

這是一個提醒:程式碼裡的註解會過期、也會寫錯,與資料庫是不是真的那樣是兩件事。這一塊開頭那個「整合功能沒在用」的錯誤前提,也是同一種狀況。

第 7 條:刪附件的安全檢查只做一半(低)

問題:程式算出了「該過濾掉哪些檔案」,接下來卻用回了沒過濾的那一份清單。這是明確的程式錯誤。

本報告撰寫時開檔核對,一行未改。

目前打不到——現在的操作流程一次只會傳一個檔案編號。但未來如果做批次刪除功能,會在使用者不知情的情況下刪錯檔案,而且不會報錯。

這一條是自動工具的一個盲點,值得記住

工具兩次掃描都沒有報它(第一次與後來的重查都沒有)。原因是它的推論停在一個問題上:「現在打得到嗎?」——答案是打不到,所以判定不成立。

「程式寫錯了」與「現在有人打得進來嗎」是兩件事。 我們的方法擅長回答後者,前者要靠人開檔看。


§7

這塊的結論

一句話:這塊的技術檢視品質是全案最好的一批(六輪覆核全部完整跑完,唯一一批做到),但它同時撞出了全案散布範圍最廣的一次密碼外流——一組可以繞過所有客戶隔離的資料庫密碼,散在 249 個檔案裡。

建議:

  1. 第 1 條建議最優先——它是這塊唯一的高風險,而且拿到的那組帳號可以繞過所有客戶隔離。三步的順序不能顛倒,先堵住再發生的路,不然清乾淨了還會再長回來。
  2. 第 2 條的兩件產品決策都已經裁完了(後端要補上權限檢查、清單分兩套邏輯),現在純粹是技術工作。要注意的是清單那件要做兩步:先讓後端分得出是哪一頁在呼叫,才談得上各套各的規則。
  3. 第 4 條與主專案快取服務那一處一起清——真正「程式寫死不驗」的目前是三處(GitHub 兩處+快取一處),同一種病、同一種修法。原本列的員工帳號目錄與寄信這次查證後已不計入。
  4. 第 5 條影響範圍是全部程式庫,不只這一塊——它不屬於任何單一模組,建議另外當成一件事處理。
  5. 第 6 條建議跟第 1 條一起清——那是同一種病(憑證寫進版本控制)。🔴 但它要跟第 5 條分開追:兩者是同一支腳本相鄰的兩行,合在一起做,很容易改完連線就收工、漏掉那組帳密。另外要先去後台確認那個帳號是不是真的唯讀,那會決定它的嚴重程度要不要往上調。

另外要提醒:這塊功能後來整組搬過家、有重新檢視過。重查確認:最早那六張工單開出之後,經過一次大規模的程式重整,一件都沒有被順手修掉。 詳見〈意見回饋重新檢視〉。

統計
檢視輪數 7 輪(原 6 輪 158 個檔案+主系統接線 1 輪,與設備清冊並排共 8 個檔,沒有新發現)
通過的發現 19 條(去重後歸成 7 件事——原為 6 件,本次內化把打包腳本內嵌帳密那項從第 5 條底下獨立出來,成為第 6 條)
最嚴重 0 條
高風險 1 條
已修 0 條
已開工單未排期 7 張(CM-1629~1634,加上本次新開的 CM-1998)

你想知道 看哪裡
搬家之後這些問題還在不在 意見回饋重新檢視
我們用什麼方法查、結果有多可信 檢視方法與工具
其他模組的檢視結果 回總報告首頁