「在缺乏『簽章(Signature)』與『不可否認(Non-repudiation)』的系統中,任何表面上的交易紀錄,都只是沙上城堡。」
最近剛好參與到一個特別的案例當中,雖然在台灣的系統有很多類似的設計,但是這次實在太有感,想了想還是用故事的方式分享出來,話說。。。
在一個名為「Pointland」的數位國度,人人使用點數交易買賣虛擬商品。有一個名為 Alice 的大型點數交易平台。Alice 擁有一個很受歡迎的 App,這個 App 上讓使用者可以用點數兌換商品。但 Alice 不想自己處理所有商品的交易流程,於是找來了 Bob —— 一個第三方開發商。
🧩 交易流程
Bob 為 Alice 設計了一個交易網站,這個網站的特性是:它只能在 Alice 的 App 的 WebView 裡運行。也就是說,這個網站不接受一般瀏覽器直接訪問,只有從 Alice 的 App 裡打開才會跑起來。Bob 認為這樣可以確保交易只在 Alice 的生態系統裡進行。
🔒 隱藏的風險
然而,所有的點數扣除和交易請求都是通過前端的 JS SDK 在這個 WebView 裡發起並完成的,Alice處理完這些所有細節,她也在App裡盡可能做了非常多安全驗證與保全措施,但是作為一個第三方網站, Bob 的後端並沒有拿到任何交易驗證的資訊。換句話說,Bob 的伺服器完全不知道這筆交易是真是假,只能相信 Alice 的 App 中的Webview說交易已經成功了。
⚠️ 問題浮現
某天,一個安全測試人員發現,只要用簡易的MITM手段攔截Webview traffic,就能取得user token,再透過模擬扣除點數的行為,就可以輕易偽造交易請求,因為沒有後端的驗證機制,這些交易就能被輕易地「假造」。Bob 這時才發現,原來整個流程缺少了一個後端的校驗環節,他完全沒有辦法去核實這些交易到底是不是合法的。
結論是...無解
Bob開發團隊的SA,大概是得到了大語言模型的加持,設計了一套非常複雜的驗證體系,極大地增加了開發攻擊難度,複雜到可能連Alice與Bob團隊的所有人都相信這個問題已經解決了。
我還記得當年密碼學教科書上有關Bob & Alice的所有示意圖中,大概就有類似的內容,所以看到這個案子的時候,我第一個反應就是,只要Alice不改,那Bob搞得再怎麼複雜,最終大概就是增加bug的程度會比解決問題的程度來的大得多,簡單地說,Alice是在整個體系裡,是唯一知道交易是否存在與交易完整資訊的人,如果她不提供資訊給Bob,那Bob就無法確認這個交易資訊是否為真。
兩個解藥
又夢回當年,課本教的是,Alice只要隨著這封信附上一串簡單的簽章,這個簽章只有Alice能發,而且Bob可以透過Alice更早之前給的算法來驗證,這樣只要簽章錯誤,我們至少知道Alice的信被改過,可以棄用這封信的資訊;亦或,出社會後,比較常見的方案是Alice透過另外一個渠道,完全只有兩人知道且無法被篡改的路徑來傳輸這封信。
這兩個方法都是很常見且非常有效的,不過在這個案例中,Alice的開發團隊,大概有什麼難言之隱吧,預設立場就是不改,加個digest可以研議個大半年,基本webhook event也不會做,然後怪Bob團隊沒有更早通知他們有這樣的設計問題,聽到後,有點哭笑不得,彷彿看到一個人指著街上的路人大罵...你怎麼不告訴我,我是傻子。
我是覺得Bob還好,發現的早,後面要是有John/William/Bill...各家第三方開發商,自求多福吧!
永動機
Bob團隊在設計解決方案的時候,興致勃勃地弄了好多花樣,請我幫忙review,看完後,我腦海中浮現的第一個念頭是永動機,如果知道熱力學第二定律,是不是就不會花時間去做這些理論上很難甚至注定無法完成的事呢?我有點慶幸當年母校的老師們在這些基礎課程上,還是有要求的。不然依照我的個性,估計也會弄個永動機出來。
這跟SQA有什麼關係?
當然有!
因為這個問題在開發中期就有被我們提出來,雖然我們不進行所謂的安全測試,但這種比較偏基本系統設計偏誤,所以在API測試當中就確認會有這些問題。。。中文不好表達複數,沒錯,Alice還不知道是"這些"。
我們的業務裡不含安全測試,但如果有安全疑慮,我們還是會口頭上/郵件裡/報告中提醒客戶,別上線裸奔,但要不要接受,想不想改,就完全取決於管理者們的智慧了。