17,333,335,124,315。這是一個 16 歲的高中生在凌晨兩點盯著螢幕算出來的數字,代表他手上那張偽造的通行證,理論上能碰到的微軟內部資料大約有 17 兆筆。
這幾天這則新聞在 Threads、IG 被轉了很多次,版本越傳越誇張。我們團隊讀完研究員本人寫的原文後,第一件事是回頭確認自家產品的登入驗證,因為整起事件的核心只有一句話:系統有檢查 JWT token 裡寫了什麼,卻沒有檢查那張證件的簽章真不真。這個錯誤很基本,用 AI 快速寫出來的系統也很容易犯。
這篇文章分三塊:事件本身到底發生什麼(包含網路上傳錯的部分)、JWT 驗證與簽章是怎麼一回事、還有你今天就能拿去問工程師的自查清單。事件細節以研究員 Faav 發表的原始技術文章為準,他在文中說明這篇曾經過微軟審閱修改;另外參考 Help Net Security 與 iTnews 的報導交叉比對。
微軟 Titan 漏洞事件整理:三十秒看懂發生什麼事
先講結論:研究員用一張「沒有簽章」的偽造 JWT token 冒充管理員,拿到了對微軟內部分析平台 Titan 下 SQL 查詢的權限。他通報後微軟四天內把端點關掉,並發了 5,000 美元漏洞賞金。整起事件的重點整理如下:
項目 | 內容 |
|---|---|
研究員 | 網名 Faav,16 歲,課餘做漏洞賞金,去年 15 歲時就回報過微軟訪客登記系統的個資問題 |
被打穿的系統 | Titan,微軟內部的資料分析平台,前端要員工連 VPN 才進得去 |
漏洞本身 | 後端只檢查 token 內容(租戶、受眾、應用程式、使用者),完全沒驗證簽章 |
利用方式 | 偽造一張 alg 設為 none、簽章留空的 token,把使用者欄位填成 admin |
理論上碰得到的範圍 | 17 個分析資料庫、9,863 張資料表,估計約 17.3 兆列(含歷史與重複資料) |
實際看了什麼 | 平台中繼資料(約 2.5 萬筆帳號紀錄)與兩筆 Bing 分析樣本,沒有下載任何客戶資料 |
時間線 | 8/25 發現、9/5 打通並當天通報、9/9 端點關閉、9/17 領到 5,000 美元 |
幫手 | 研究員自己寫的 AI 漏洞掃描機器人 Antares,底下跑 Codex 與 Claude |
網路上流傳的版本有幾個地方講錯了,其中兩個會直接誤導你對事件嚴重性的判斷:
流傳的說法 | 原文實際寫的 |
|---|---|
「存取了高達 17 兆筆資料」 | 17 兆是「技術上碰得到」的估計值,他本人強調從沒碰過任何客戶資料或個資 |
「取得 2.5 萬名員工個資」 | 約 2.5 萬筆是帳號與 email 紀錄,其中員工 email 約 1.8 萬筆,只涵蓋跟 Titan 有關的部分員工 |
「/v2/Query 完全沒有防護」 | 它有檢查 token、不帶會回 401,只是沒驗簽章;門有關,只是那把鎖是壞的 |
「跑一行指令就撈到 2.5 萬筆員工資訊」 | 列出資料庫清單的指令只會看到清單,員工資料是之後查中繼資料表才看到的 |
把「理論上碰得到」和「實際拿走」分清楚很重要。這起事件真正的教訓在於,一個驗證環節沒做好,就讓一整座資料倉庫的大門形同虛設,這次只是剛好白帽先發現。
JWT token 是什麼:三段文字,簽章才是那張證件照
一句話說明:JWT token 是伺服器發給使用者的一張數位通行證,裡面寫著「你是誰、可以做什麼」,最後附上一段只有伺服器做得出來的簽章,用來證明這張證不是別人偽造的。
很多網站登入後,瀏覽器每次呼叫 API 都會帶著這張通行證。它長得像一串亂碼,用兩個句點切成三段:
段落 | 裡面裝什麼 | 別人看得到嗎 | Titan 事件中的狀況 |
|---|---|---|---|
Header 標頭 | 用哪種演算法簽章,例如 RS256 | 看得到,只是 Base64 編碼 | 被改成 alg: none |
Payload 內容 | 使用者是誰、屬於哪個租戶、有效期限 | 看得到,任何人都能解開 | 使用者欄位被填成 admin |
Signature 簽章 | 用伺服器金鑰對前兩段算出的一段值 | 看得到,但只有持金鑰的人做得出來 | 直接留空,系統照樣放行 |
關鍵在第三段。前兩段只是編碼,誰都可以解開、修改、再重新編碼回去。簽章的作用,是讓伺服器確認「這兩段內容是我發出去的、中途沒被動過手腳」。伺服器如果不驗簽章,JWT token 就等於一張手寫名牌,想寫誰的名字都可以。
Faav 在原文用了一個很貼切的比喻:Titan 像一個夜店保鑣,每張證件上的名字都仔細核對,卻從來不看照片。他還形容整個驗證機制像一間每扇門都有刷卡機的飯店,可是任何一張房卡都能打開任何一間房。
如果你對「API」這個詞還不太熟,可以先看我們寫的API 是什麼:為什麼老闆也該懂這個技術名詞。JWT token 就是 API 用來確認「來敲門的是誰」的那張證件。
我們自己的產品線也是靠 JWT token 串起來的。恆遠會員中樞系統負責所有自家產品的註冊、登入與權限,發給各產品的單一登入 token 用 RS256 私鑰簽章,每個產品驗證時把演算法鎖定在 RS256,收到 alg: none 或其他演算法一律拒絕。驗證邏輯集中在一處,要檢查、要補洞都只改一個地方。如果你的系統每個服務各寫一套登入驗證,很歡迎跟我們聊聊怎麼收攏。這種把身分驗證收攏到單一入口的做法,就是企業單一登入 SSO 在解決的問題。
這個洞是怎麼一步步被走完的:從一張 VPN 提示頁到管理員權限
先講結論:整條路徑沒有用到什麼高深技巧,每一步都是撿系統自己留下的線索。照時間順序拆開來看,你會發現每個環節其實都有機會把它擋下來,這對防守方才是重點。
第一關,前端上鎖擋不住後端。Titan 的網頁介面要員工連 VPN 才看得到,但那支 AI 機器人掃描微軟的子網域時,找到一台架在 Azure 雲端上、直接對外的 API 主機。前端上鎖、後端 API 卻裸奔,這種落差在企業系統裡其實很常見。
第二關,說明書公開在外。這台主機有一份公開的 Swagger 文件,也就是 API 的使用說明書,把四支 API 全列了出來,其中一支可以直接接受 SQL 查詢指令。內部 API 的說明書掛在公開網路上,等於把地圖印好送給對方。
第三關,舊設定檔還躺在網路存檔裡。查詢需要填資料表名稱,說明書沒給範例。Faav 到網路時光機(Wayback Machine)翻出 Titan 在 2023 年的登入頁快照,從當時留下的 Apache Superset 設定裡找到 56 個資料表名稱。系統早就改版,舊設定卻沒人清掉。
第四關,系統一路把答案送上門。不帶 token 呼叫會回 401。接下來十天,那支 AI 機器人拿一張從自己測試環境簽出來的 token,每次只改一個欄位,看系統回什麼錯誤:
每次改了哪個欄位 | 系統回的錯誤 | 透露了什麼 |
|---|---|---|
用研究員自己測試環境的 token | 租戶錯誤 | 系統有檢查租戶 |
租戶改成微軟的 | 受眾(audience)錯誤 | 過了租戶這關 |
受眾改成 Titan 的 | 應用程式白名單錯誤 | 過了受眾這關 |
應用程式 ID 改成白名單內的 | 找不到使用者 | 已經進到使用者查詢,而簽章從頭到尾沒被檢查 |
這張表是整起事件最值得工程師看的地方。內容一直在改、簽章一直沒動,系統卻一路放行,這就等於自己承認沒在驗簽章。更糟的是每一層都回傳清楚的錯誤訊息,等於一步一步告訴對方下一格要填什麼。錯誤訊息給太細,本身就是一種資訊外洩。
最後一關,一個很不起眼的字。Faav 把整張 token 換成 alg 設為 none、簽章留空的版本,一樣通過,只剩「使用者是誰」卡住。AI 一直試 email 格式的帳號,因為那個欄位照規格應該放 email。9 月 5 日凌晨一點多,Faav 想到後端可能拿這個欄位去對應內部帳號名稱,於是填了 admin。查詢回傳一個「1」,他就以 Titan 管理員的身分執行了查詢。用他自己的話說:有時候答案真的就是 admin。
JWT 驗證最常見的四種寫錯法,Titan 中的是最嚴重那一種
先講結論:JWT 驗證出問題,九成都落在下面這四種寫法。Titan 犯的是第一種,也是最致命的一種,因為它讓任何人都能自己簽發一張管理員通行證。這一節寫給要維護自家系統的開發者,把該檢查的地方一次列清楚。
寫錯法 | 實際長什麼樣 | 會被怎麼利用 | 正確做法 |
|---|---|---|---|
只解碼、不驗簽章 | 把內容讀出來就直接拿來判斷身分 | 自己做一張 token,想當誰就當誰 | 一律用 verify 類函式,簽章不過就拒絕 |
接受 alg: none | 讓 token 自己決定演算法,none 也照收 | 送一張沒有簽章的 token 就過關 | 在伺服器端寫死允許的演算法清單 |
演算法混淆 | 該用非對稱簽章卻沒鎖死,被換成對稱 | 拿公開的公鑰當密鑰去偽造簽章 | 驗證時指定演算法,公鑰與密鑰分開管理 |
不檢查期限與來源 | 只驗簽章,不看效期、簽發者、受眾 | 拿過期或別的系統發的 token 繼續用 | 效期、簽發者、受眾一起驗,token 效期設短 |
這些都不是新問題。OWASP 把「身分驗證失效」列在 API 安全風險的第二名,白紙黑字寫出「接受未簽章或弱簽章的 JWT(alg: none)」就是典型案例。IETF 在 2020 年發布的 JWT 最佳實務 RFC 8725 也要求:程式庫必須讓呼叫端指定允許的演算法,不能照單全收 token 自己宣告的那個。
程式庫本身也會出包。2026 年 1 月公開的 CVE-2026-23993 就是一例:一套 JWT 程式庫只要遇到它不認識的演算法名稱,none、None、foo 甚至空字串,都會跳過簽章驗證。就算自己的程式碼寫對了,用到沒更新的套件一樣會中招,所以相依套件的版本也要跟著顧。
用 Node.js 最常見的 jsonwebtoken 套件示範,有洞的寫法和補好的寫法其實只差幾行。這段可以直接拿去對照自家程式碼:
import jwt from 'jsonwebtoken'
// 有洞的寫法:decode 只把內容解出來,完全沒驗簽章
function getUserUnsafe(token) {
const claims = jwt.decode(token)
if (claims.tid !== EXPECTED_TENANT) throw new Error('tenant')
if (claims.aud !== EXPECTED_AUDIENCE) throw new Error('audience')
return db.user.findByName(claims.upn) // 內容可以隨便填,等於沒鎖
}
// 補好的寫法:先驗簽章,並寫死演算法、受眾、簽發者
function getUser(token) {
const claims = jwt.verify(token, PUBLIC_KEY, {
algorithms: ['RS256'], // 只接受這個演算法,擋掉 none 與混淆
audience: EXPECTED_AUDIENCE,
issuer: EXPECTED_ISSUER,
})
return db.user.findByExternalId(claims.oid) // 用不可變的 ID 對應使用者
}有洞的版本看起來也很「嚴謹」,租戶、受眾都檢查了,Titan 甚至還多查了應用程式白名單。問題是這些檢查全部建立在「token 內容可信」這個前提上,而內容可不可信,只有簽章能證明。少了那一行 verify,前面查得再多都是白工。
補好的版本還改了一個細節:用使用者不可變的 ID 去對應帳號,不用那種可以隨便填的名稱欄位。Titan 就是拿一個本該是 email 的欄位去比對內部帳號,才讓 admin 這個字變成管理員。這也提醒一件事:拿來查身分的欄位,要挑使用者改不動的那個。
AI 花十天找不到 admin,卻也很會寫出這種洞
先講結論:這起事件裡 AI 站在兩邊。攻擊端的 AI 很會磨、很有耐心;而防守端的系統如果也是 AI 快速寫出來、沒人審過,這種洞只會越來越多。這是我們最想提醒中小企業老闆的一點。
那支 AI 機器人做了十天研究員不用親自做的苦工:列舉子網域、逐欄解讀錯誤訊息、把一張沒有簽章的 token 一路推過四層檢查。但它卡在最後一步,因為它認定那個欄位照規格是 email,就一直試 email,想不到後端工程師其實拿它當內部帳號名稱用。Faav 的結論是:AI 的耐力加上一次人類直覺,缺了任何一邊都找不到這個洞。
攻擊成本正在快速下降。Imperva 2026 年惡意機器人報告統計,2025 年自動化流量已經佔全網 53%,超過人類,而且超過四分之一的機器人攻擊直接打 API。以前要一個資深資安人員花好幾天做的枚舉和試錯,現在一支機器人就能在背景一直跑,不喊累。
防守端的狀況也不樂觀。Veracode 的 2026 年生成式 AI 程式碼安全報告發現,大約 44% 的 AI 寫程式任務產出了帶有已知漏洞的程式碼,各家模型的平均安全通過率只有 56%,跟前一版報告的 55% 幾乎一樣。模型把程式寫得越來越順,安全性卻原地踏步。
我們的判斷很直接:JWT 驗證這種「功能測試一定會過、只有安全測試才會掛」的程式碼,最不適合全交給 AI 寫完就上線。用正常 token 去測,寫錯的版本一樣能登入、一樣能查資料,開發者完全感覺不到問題。只有刻意拿一張偽造的 token 去打,才會發現門根本沒鎖。
我們公司自己每天就在跑 20+ 個 AI 流程,寫程式也大量用 AI。我們的做法是讓 AI 寫,但登入、權限、金流這幾塊一定有人逐行看過,而且會用偽造 token、換成別人的 ID 這類「故意使壞」的測試去打自己。如果你的系統是用 AI 快速做出來的,可以先看Vibe Coding 做出來的 App 能直接上線嗎,裡面整理了最常見的幾種坑;想從原型走到能賣的正式產品,中間差的 7 件事也值得一起對照。
簽章之外,這起事件還有三個常被忽略的破口
先講結論:JWT 沒驗簽章是致命的那一刀,但另外三個破口只要有任何一個被補上,攻擊者都很難走到最後。資安從來就是好幾層防線疊起來,不是靠單一一道牆。
破口 | 這次的狀況 | 為什麼危險 | 該怎麼補 |
|---|---|---|---|
API 說明書公開在外 | Swagger 文件任何人都讀得到,還標明哪支能下 SQL | 等於把攻擊地圖印好交給對方 | 內部 API 文件放內網或加驗證,不對外公開 |
舊設定檔留在網路存檔 | 2023 年的設定被網路時光機存下,含資料表結構 | 改版後的舊資料成了現成情報 | 敏感頁面設定不快取,定期檢查外部存檔有沒有殘留 |
錯誤訊息說得太細 | 每一層驗證失敗都回傳明確原因 | 一步步引導攻擊者填對下一格 | 對外一律回統一的模糊錯誤,細節只寫進內部日誌 |
這三件事單獨看都不算「漏洞」,比較像壞習慣。但疊在一起,就把一個原本要花很久摸索的攻擊,縮短成十天就能走完。防守方要建立的觀念是:不要假設「反正沒人知道這支 API 在哪」,網路上的掃描機器人一天到晚在找這種沒公開連結、卻對外開著的端點。
金鑰與機密外洩也是同一類問題,我們在Zeabur 資安事件白話拆解裡整理過中小企業的止血清單,跟這篇可以搭著看。簽章用的私鑰、資料庫密碼這類機密該怎麼存、怎麼輪替,另外整理在企業機密資料 secrets 管理採購指南。
這裡也順帶破解一個常見迷思:很多人以為「我們公司又不是微軟,沒人會盯上我們」。真相是,掃描機器人不挑對象,它只是無差別地在整個網路上找有沒有對外開著、又沒鎖好的端點。規模小反而更危險,因為小公司通常沒有專職資安人員,一個洞可能開著好幾個月都沒人發現。Titan 這種等級的系統都會犯的錯,資源更少的團隊只會更容易犯。
開發者自查清單:這八項今天就能檢查自家系統
先講結論:不用等資安廠商進場,下面八項大部分工程師半天內就能自己驗完。每一項都寫了怎麼測,測不過的就是優先要補的地方。這份清單適合拿去直接問你的開發團隊或外包廠商。
檢查項目 | 怎麼測 | 沒過會怎樣 |
|---|---|---|
登入驗證有真的驗簽章 | 把 token 內容改一個字再送出去,看還過不過 | 任何人都能偽造身分 |
拒絕 alg: none | 送一張 alg 設為 none、簽章留空的 token | 不用金鑰就能簽發任意通行證 |
演算法寫死在伺服器端 | 看驗證程式有沒有指定 algorithms 清單 | 會被演算法混淆攻擊繞過 |
效期、簽發者、受眾都有驗 | 拿一張過期或別系統的 token 來打 | 舊 token、跨系統 token 可以一直用 |
用不可變 ID 對應帳號 | 看是用 email/名稱還是內部 ID 查使用者 | 可竄改的欄位會被填成 admin |
內部 API 沒有裸奔在公網 | 從外部網路直接連 API 主機網址 | 前端上鎖也擋不住後端 |
錯誤訊息不外洩細節 | 故意打錯,看回傳有沒有講出哪一關失敗 | 等於教攻擊者怎麼過關 |
JWT 相依套件有更新 | 列出套件版本,對照近期漏洞公告 | 自己寫對了,套件的洞照樣中招 |
我們的判斷很直接:買再多的網站防火牆和 CDN,也擋不住這種攻擊。防火牆看的是「這個請求長得像不像攻擊」,但一張偽造 token 送出的請求,格式跟正常請求一模一樣。真正有效的防線寫在程式碼裡,而且要有人一支一支 API 看過。這也是我們不認同「買了資安方案就能安心」的原因。
三種常見的資安檢測各自抓不同的東西,別買錯,可以看弱點掃描、滲透測試、壓力測試的差異。這類「功能正常、驗證有洞」的問題,自動掃描工具往往抓不到,因為掃描器不知道你的商業邏輯該長什麼樣。若公司要把這些檢查變成長期制度、而不是出事才做一次,可以參考CNS 27001 與 ISO 27001 資安管理制度指南。
用 AI 快速做出來的系統特別要留意這一塊。AI 寫的登入功能測起來都會過,但常常就少了驗簽章那幾行。如果你的系統是外包或用 AI 趕出來的、自己看不出有沒有這種洞,我們的 Vibe Coding 上線前健檢會逐項檢查登入與權限、API 金鑰外洩、金流流程,出一份不是工程師也看得懂的報告和修復優先順序。先聊聊你的系統現況,值不值得做、先看哪一塊,我們會直接告訴你。
ℹ️我們怎麼看
接下來兩三年,這種「系統功能全都正常、只是少驗一個環節」的事件會越來越多,因為越來越多程式是 AI 快速生出來、沒人逐行審過就上線的。Veracode 的數據已經顯示 AI 寫的程式有四成帶著已知漏洞,而攻擊端的 AI 只會越來越有耐心。我們在自己做的系統裡的選擇是:簽章一定驗、演算法一定寫死、身分一定用不可變 ID 對應,這幾條寧可開發時多花時間也不省。給老闆一個最簡單的判斷方法:問你的工程師「有人拿一張自己偽造、沒有簽章的登入證來打我們系統,會怎樣?」答得出來、也實際測過,就先放心;答不出來,就該排時間檢查了。
ℹ️我們做過這件事
恆遠目前有 40+ 企業客製案落地,自家產品線的登入與權限也是我們自己做的共用中樞,發出去的單一登入 token 用 RS256 簽章、驗證時把演算法鎖死,這一塊一直是我們交付前花最多時間確認的部分之一。
例如我們做的高雄市幼兒園招生系統,同一套系統要服務家長、園所、教育局三端,每一端能看到、能改的資料都不一樣,權限一步都錯不得。
看到這裡,如果你也在想「我們的系統登入與權限到底做得對不對」,我們很樂意聽你聊聊現在的情況,一起看看哪些地方該先補。
看到這裡,如果你也在想「我們家的登入驗證有沒有這種洞」,很歡迎把系統現況丟過來,我們陪你看從哪一支 API 開始檢查最划算。
Q這次微軟真的外洩 17 兆筆資料嗎?
沒有。17 兆是研究員估算「技術上碰得到」的資料量,他強調自己從沒下載或碰過任何客戶資料與個資,只看了平台中繼資料和兩筆分析樣本就通報微軟。網路上「存取了 17 兆筆」的說法是把「能碰到」誤當成「已拿走」。
QJWT token 沒驗簽章為什麼這麼嚴重?
JWT 的前兩段內容任何人都能解開、修改再重新編碼,簽章是唯一能證明「這張證是伺服器發的、沒被動過」的部分。系統不驗簽章,等於接受任何人手寫的名牌,想冒充誰就冒充誰。這次攻擊者就是把使用者欄位填成 admin,直接變成管理員。
Qalg: none 是什麼?該怎麼防?
alg: none 是 JWT 規格裡「這張 token 不簽章」的宣告,本來只用於受信任的封閉環境。有洞的系統會照著 token 自己宣告的演算法去驗,看到 none 就跳過簽章檢查。正確做法是在伺服器端寫死允許的演算法清單(例如只收 RS256),收到 none 或清單外的演算法一律拒絕。
Q我不是工程師,要怎麼確認公司系統安全?
問你的開發團隊或外包廠商一個問題就好:「有人拿一張自己偽造、沒有簽章的登入 token 來打我們系統,會發生什麼事?」答得出來、也實際測過就相對安心。答不出來,代表沒人驗證過這一塊,建議安排一次上線前的資安健檢。
QAI 寫的程式碼可以直接上線嗎?
功能可以,但登入、權限、金流這幾塊建議一定要有人審過。業界研究顯示約四成 AI 生成的程式碼帶有已知漏洞,而且這種洞用正常操作測不出來,功能完全正常,只有拿偽造請求去打才會現形。上線前做一次針對性的審計,比出事後補救便宜得多。
Q這種漏洞,一般的弱點掃描工具掃得到嗎?
多半掃不到。這類「功能正常、驗證邏輯有洞」的問題屬於商業邏輯層面,掃描器不知道你的系統該怎麼判斷身分與權限,很難自動判定。要靠人工的程式碼審查或滲透測試,用偽造 token、換別人 ID 這類手法去驗證。
AUTHOR
恆遠數位編輯團隊







留言(0)
尚無留言,成為第一個留言的人吧!