資訊安全

Canvas LMS 3.65TB 史上最大教育資料外洩:ShinyHunters 兩週兩次得手的技術啟示

2026.05.14 · 60 次瀏覽
Canvas LMS 3.65TB 史上最大教育資料外洩:ShinyHunters 兩週兩次得手的技術啟示

8,809 所大學、2.75 億用戶、學生對老師的私訊全裸 — 為什麼這場攻擊對所有 SaaS 業者都是必修課

5 月最大的資安事件不是金融、也不是政府,是教育。Instructure 旗下的 Canvas LMS — 全球最被廣泛採用的學習管理系統之一 — 在 5 月 1 日到 5 月 11 日這短短十天內被駭兩次。第一次,攻擊者 ShinyHunters 竊取了 3.65TB 的資料,涉及 8,809 所大學與教育機關、約 2.75 億名使用者,包括姓名、Email、學生 ID 與最敏感的「學生與老師之間的私訊紀錄」。Instructure 公開聲明問題已修復後,攻擊者在 5 月 7 日再次入侵,把 Canvas 登入頁直接換成勒索訊息。5 月 11 日,Instructure 對外承認已與駭客達成協議、據稱資料已銷毀。


這場攻擊在技術細節層面上沒有公布完整的 root cause,但從 ShinyHunters 過去手法、以及併發發生在 Cushman & Wakefield 的 Salesforce 50 萬筆外洩,幾乎可以推論主要切入點是第三方整合的 OAuth token 與 API key 失竊,加上過度寬鬆的 IAM 角色讓單一憑證可以一次 dump 整座 multi-tenant 資料庫。


對於做 Laravel + MySQL + Nginx 的開發團隊來說,這場事件有四個直接可執行的教訓:


一、OAuth Token 永遠要設範圍與 TTL


許多 Laravel 應用為了開發方便,會給第三方整合「全帳號讀寫」的 scope,加上不過期的 token。Sanctum 與 Passport 都支援 token abilities 與 expires_at,請務必啟用,並用 cron 每天 revoke 一次超齡 token。


二、MySQL 一定要有 row-level 與 tenant-level 的 query guard


Laravel 的 Global Scopes 是現成的工具,把 tenant_id 條件強制掛在 Eloquent 上,任何「忘了過濾 tenant」的 controller 都會被擋下。


三、Nginx 必須做 API Rate Limit 與 Geo-fencing


limit_req_zone 加 limit_req 是基本盤;對於管理後台與資料 export endpoint,建議再加上 allow/deny 名單,或用 ngx_http_geoip2_module 限制非預期地區。


四、Audit Log 必須是 append-only


把高敏感操作(資料 export、權限變更、登入失敗超過閾值)寫進獨立的 audit_logs 表,並用 Laravel 的 Observer + 資料庫層級的 BEFORE UPDATE/DELETE trigger 禁止任何修改。事後鑑識能不能成立,往往就在這一張表。


從攻擊面廣度看,Canvas 事件最可怕的不是駭客有多厲害,而是「一個 SaaS 一被駭,影響的是上千個機構與兩億多人」這個 multi-tenant 結構特性。SaaS 的商業模型本身就是高槓桿,但這也意味著它的攻擊面是 multi-tenant 槓桿過後的攻擊面 — 一個被洩漏的 admin token,就可能等於萬人份的爆破。


我的觀點


這場事件對所有正在「把客戶資料集中到一個系統」的外包商來說都是警鐘。當你提案幫某連鎖企業做後台管理系統時,過去的賣點是「集中管理、降低成本」;2026 年之後,這個賣點要加一條:「集中管理、降低成本、但資料分艙」。技術上這意味著:每個客戶(或租戶)的資料必須在 MySQL 上以 schema-level 或至少 row-level 隔離,加密金鑰要 per-tenant,OAuth token 必須有 ability scope,audit log 是 append-only。這些不是高深的東西,但會把你跟「便宜的接案工作室」區隔開來 — 客戶不會因為你寫得快而選你,但會因為你有資安交付物而願意付兩倍的錢。


資料來源