任何前端應用都不可能被安全保護? - kuzzle

banq發表於2022-04-25

嘗試使用低效技術保護前端應用程式可能很危險。
我從不同的來源(Callstack、Jscrambler、Tabris、Nativescript、Reactnativecode)看到了許多文章,詳細介紹了使用混淆、自定義加密(XORing與重複使用金鑰等......)等技術來保護前端應用程式的安全。
事實上,應用程式的原始碼由客戶端支配,它可以隨意研究和修改,它會了解App內部機制或恢復裝置上儲存的所有資料。
因此:
  • 不要相信前端應用程式
  • 不要推出你自己的加密技術
  • 不要使用可預測的加密金鑰
  • 不要重複使用相同的金鑰
  • 混淆是不安全的
  • 確保你的後端安全


認證
傳送認證資訊是透過SSL連線安全進行的,因此在大多數情況下,通訊的保密性得到了保證。

由於以下原因,沒有必要為每個客戶的認證新增一個簡單的XOR和重複使用的金鑰的基本密碼加密層。

  • 為每個客戶和每個請求重複使用金鑰使加密變得脆弱,因為透過頻率分析有可能猜出資訊。
  • 由於金鑰儲存在裝置中,你只需要下載應用程式就可以知道它。

新增一個加密層可能是一個好主意,以避免在中間人用假SSL證照攻擊的情況下資料被洩露。

但是,為了實現強大的加密,至少有必要:
  • 使用與密碼大小相當的金鑰
  • 為每個使用者和每個請求使用一個不同的金鑰
  • 用Diffie Helman型別的非對稱加密演算法來協商這個金鑰。

這或多或少與在你的應用程式中實現一個自定義版本的SSL相同,但請記住,統治你自己的加密技術永遠不是一個好主意。
使用其他安全技術(如SSL Pining)來防止MITM攻擊要容易得多。

儲存敏感資料
當需要在前端應用程式中儲存敏感資料時,最好使用開發環境的建立者所提供的機制。 

例如,在使用React Native的移動應用程式中,開發人員可以使用蘋果的Keychain或Android的Keystore。這些機制使得從裝置上提取敏感資料更加困難,但也不能認為它們是完全安全的(例如,蘋果的鑰匙鏈被利用)。

在任何情況下,都沒有必要增加一個用可預測的金鑰製作的額外加密層,因為攻擊者可以逆向工程應用程式並重新生成金鑰。
或者更簡單,直接訪問儲存在記憶體中的金鑰。

此外,在前端應用程式中新增一個自定義的加密層是適得其反的,會消耗不必要的CPU資源進行加密/解密,從而消耗電池。

混淆原始碼
雖然我可以理解開發者可能想讓原始碼的逆向工程更加困難,但混淆決不能被視為一種安全做法。

它最多可以阻止一些攻擊者,但有動機的人總是可以對程式碼進行反向工程。
特別是在使用開源混淆器的情況下,因為它是已知的,而去混淆器肯定已經存在。

此外,混淆將使程式碼很難被不同的Javascript執行系統解釋和最佳化,並將導致應用程式的效能大幅下降。

保護你的後端
正如我們所看到的,一個前端應用程式是不安全的。因為不可能控制客戶的裝置,所以不可能確保它不被破壞。 
大部分的安全元素必須在後端落實到位。
確保後端安全並沒有什麼神奇的秘方,是一套良好的程式設計實踐使你能達到最佳效果。

永遠不要相信使用者的輸入
從HTTP請求的正文,到標頭檔案或cookies,所有可以被使用者操縱的資訊都不能被信任。
對使用者輸入的天真利用會導致各種攻擊的發生。

  • SQL隱碼攻擊和NoSQL隱碼攻擊
  • 遠端程式碼執行
  • 特權升級

在應用程式中使用輸入資料之前,總是有必要對其進行檢查和消毒。

限制DoS
拒絕服務攻擊試圖使一個應用程式不可用。
例如,有可能傳送非常大的JSON有效載荷,這可能阻礙甚至凍結你的應用程式。
緩解攻擊:在最低層限制有效載荷的大小,最好是直接在網路層限制。

如果你的後端是用Node.js編寫的,那麼在建立新的Promises時也有必要提高警惕。
事實上,一個Promise會被自動傳送到事件迴圈中,然後就不可能在它被解決或拒絕之前撤回它。
因此,攻擊者有可能在一條路線上傳送大量的請求,產生Promises,使事件迴圈達到飽和。

緩解攻擊:實現一個只使用回撥的併發請求限制系統。使用回撥進行開發並不有趣,但回撥只是方法的指標,在呼叫之前不使用資源。只在請求限制系統之後使用Promises。

防止暴力攻擊
為了防止對使用者認證的暴力攻擊,有必要對連線嘗試的次數進行限制。
這種限制可以採取在認證途徑中加入X次嘗試後的阻止形式。

安全地儲存密碼
在2019年,仍有一些公司以純文字方式儲存使用者的密碼。

必須不惜一切代價避免這種做法,以便在你的應用程式發生資料洩漏時保護你的使用者。不僅是你自己的應用程式:大多數使用者在許多賬戶中重複使用同一個密碼。密碼洩漏的影響可能是災難性的,無論是對你的使用者還是對你公司的形象。

 密碼必須使用單向加密函式或雜湊函式來儲存。

雜湊函式的選擇應該基於一個強大的演算法,例如bcrypt。如果可以的話,透過使用金鑰拉伸使弱的密碼變得更強,為了增加安全層,你也可以對密碼加鹽加胡椒。

還有更多
後臺有很多可能的攻擊,而且大部分都是鮮為人知或不為人知的。
例如,兩個字串的簡單比較會導致定時攻擊的漏洞,並允許攻擊者猜測密碼或令牌。
但是,使用一個眾所周知的正規表示式庫也容易受到ReDoS攻擊。

 這就是為什麼保障後端安全不是一項輕而易舉的任務,必須委託安全專家對開發人員進行培訓,但也要對程式碼進行審計,以確保有儘可能少的漏洞,因為完美的安全是不存在的。

結束語
在開發一個應用程式時,必須自始至終考慮到安全問題,反思必須涵蓋從後端到前端的整個應用程式範圍,包括通訊渠道和託管。 
安全是昂貴的,因此常常被忽視。這就是為什麼最好使用由具有必要技能和知識的工程師設計的框架和後端,以確保終端使用者的充分安全。
我要感謝協助我寫這篇文章的整個Kuzzle團隊,特別是Sebastien Cottinet和Yannick Combes在安全和密碼學方面的專業知識。


所有的客戶都是潛在的惡意的。保護你的後端。
前端有一些安全問題,大多歸結為:

  • (JS)使用JS作用域,使你的應用程式的功能與使用者的指令碼隔離。
  • 不要暴露你的使用者資訊。
  • 儘可能少地保留支付資訊居民。這意味著在銷燬前清除表單欄位,並且永遠不要記錄原始PCI資料。
  • 不要暴露你自己的密碼金鑰。使用使用者特定的令牌,並在後端解決它們。
  • 我不應該這樣說,但在傳遞所有輸入之前,要對它們進行消毒。

相關文章