19 February 2014

在六年前我有一個 專案 (side project),一個簡單的網站服務,它沉寂了很長的一段時間,到了最近用戶才開始升到某個水準,現在還活著好好的。因為人數多了,奇怪的人也變多了。有用戶開始寫 robot ,做一些自動留言、或甚至是越權的攻擊。

那個賽專案一開始我就決定了架構:Single page + Pure client side app ,這架構在現在已經不稀奇,不過該網站是在六年前寫成的,那時才沒有什麼 Angular 可用咧,連 Chrome 瀏覽器才剛誕生沒多久。靠的是 GWT + Flash 硬拼,我可以說還挺前衛的。

全部邏輯都寫在 client side,而 server 只剩下薄薄的一層 web servcie,在架構上比用 server side session 輕很多,state 都可以留在 client browser 裡,不用一直把參數在頁面間帶來帶去,也不用擔心 client 和 server 的 state 有落差,我開發時就感受到這架構比過去那些純 server side 的網頁還直覺,不用歪著頭寫程式。而 offload 到 client 也有助 server scalability,因為 server 做的事變少了。無怪乎新的開發者現在都偏好 single page app 。

好,回頭說說攻擊,因為該網站是賽專案,我什麼防護措失、權限檢查都沒寫,網站算是脫光著衣服在服務,六年來到也風平浪靜... 不過最終它還是被破解了,僅管 GWT 是 Java compiled 成 js,再經過混淆過,這算是混的不能再混的 js 。還是有人可以從中爬出一些蛛絲螞跡,進行反組譯。

當然啦,接下來就是一陣攻防,起初我還認定攻擊者一定看不懂混過的 js,所以防護措施我還是寫在 client side,後來一天內就被破了,這次我才意識到原來有人可以看懂那個 GWT 產生的鬼 js。才把檢驗的邏輯搬回到 server 處理。接下來就是一直補漏洞,直到所有重要權限的操作全都搬回 server 為止。

如果是正式的產品,當然不會這麼隨隨便便沒任何保護就上線。這網站一直是我實驗新概念的場所 -- "把邏輯全包在 js client 裡" 是個全新的嘗試。這個嘗試在六年後破功失敗。話說回來一個小網站也有人這麼認真惡搞,那還真是意外了,破解的人有功力有時間去反組譯那鬼似的 js,為何不自己寫個站來玩、或甚至賺錢呢?

攻擊者可以完全反組譯你的 Javascript 程式碼

今天談的安全性是關於軟體的功能被惡意使用,而不是像 server 被入侵,密碼資料庫被盜走那類的資安事件。儘管如此,這仍是安全上重要的一環。如果你有正式的產品,而且是用現在正流行的 single page app 架構,那麼你有很高的機會會在 client 裡寫邏輯。你應該設置個大前題 -- 攻擊者可以完全反組譯你的 js 程式碼 -- 來架構你的 app。需要權限的操作都要在 server 做,並做好帳戶驗證,有重要的 transaction,要採用 Nonce 保護等等。

ps. 這個賽專案不是 dinbendon。dinbendon 是用純 server side framework 寫的,很安全。不過它超肥,一隻吃 ram 的怪獸。