Filepicker 是一個非常好用的 File upload service,它可以讓你用簡單的 Javascript,就能做出超好用的圖片上傳,Backend 完全不用寫 Code,就可以讓使用者把圖片傳到 S3 上,詳細的介紹可以參考官網,這篇主要介紹 Filepicker 安全性問題。
簡單的 Pick & Store
Filepicker 只要簡單的一小段 code,就可以讓使用者挑選檔案,並傳到 S3:
1 2 3 4 5 6 7 8 9 |
|
但如果稍微想一下,就會發現 maxSize 和 path 都寫在前端,那如果稍微懂點 Javascript 的使用者,把這兩個變數塞別的數值進去,那他就可以傳任意大小的檔案到任意的路徑。
Filepicker 安全機制
Filepicker 提供一個 Security 機制,可以避免這個問題,流程如下:
- 跟 Filepicker 申請一個
App Secret
- 在 Server Backend 定義
policy
,並用 Base64 加密。 - 在 Server Backend 使用
App Secret
加密policy
,產生出signature
- Javascript 在呼叫 API 的時候,送出
policy
和signature
做驗證。
但是官網提供的 Security文件 是用 python 做範例,這邊我們用 ruby 來一步一步教學。
申請 App Secret
到官網後台的左邊選單 App Secret
處,就可以申請一個 Secret:
注意,上面的 Use Security
勾選以後,前端送出的 request 就全部都要送 policy 和 signature,不然會失敗。
定義 policy
Policy 就是定義使用者可以用哪些功能、上傳多大的檔案、上傳路徑為何 …,詳細的 options 可以參考官網文件。
用 Ruby 先定義簡單的 policy:
1 2 3 4 5 6 |
|
接著用 Base64 幫 policy 加密:
1 2 |
|
產生 signature
有了 encoded_policy 和 app secret 就能產生 signature
1 2 |
|
Filepicker 會檢查加密後的 policy 和 Signature 是否一致,而且只有我們和 Filepicker 才知道 App Secret
是什麼,第三方如果沒有 App Secret 是沒辦法產生出 Signature 的。
使用 Security 機制
接著就可以把產生出來的 signature 和 encoded_policy 塞進 Javascript:
1 2 3 4 5 6 7 8 9 10 11 |
|
簡單測試
我們把 Server side Policy 的 maxSize 設成 1kb:
1 2 3 4 5 |
|
在 Javascript 那邊假裝惡意使用者,把 maxSize 設成 10mb:
1 2 3 4 5 6 7 8 9 10 11 |
|
接著上傳一個超過 1kb 的檔案,可以看到錯誤訊息:
小結
用了 Security 以後,就可以對網站不一樣的使用者,做不一樣的權限控管,未付費會員不能上傳檔案,因此就不產生 signature 給他,以及各種 User 檔案上傳大小限制之類的。不會因為是寫在 Javascript,而被輕鬆破解。