最近項目被安全掃描由於項目設計有問題,暴出來了一些漏洞,在修復的過程中特把經驗總結分享。
1.前后端分離和傳統架構介紹
1.1 前后端不分離
在前后端不分離的應用模式中,前端頁面看到的效果都是由后端控制,由后端渲染頁面或重定向,也就是后端需要控制前端的展示,前端與后端的耦合度很高。
這種應用模式比較適合純網頁應用,但是當后端對接App時,App可能並不需要后端返回一個HTML網頁,而僅僅是數據本身,所以后端原本返回網頁的接口不再適用於前端App應用,為了對接App后端還需再開發一套接口。
請求的數據交互如下圖:
1.2 前后端分離
在前后端分離的應用模式中,后端僅返回前端所需的數據,不再渲染HTML頁面,不再控制前端的效果。至於前端用戶看到什么效果,從后端請求的數據如何加載到前端中,都由前端自己決定,網頁有網頁的處理方式,App有App的處理方式,但無論哪種前端,所需的數據基本相同,后端僅需開發一套邏輯對外提供數據即可。
在前后端分離的應用模式中 ,前端與后端的耦合度相對較低。
在前后端分離的應用模式中,我們通常將后端開發的每個視圖都稱為一個接口,或者API,前端通過訪問接口來對數據進行增刪改查。
對應的數據交互如下圖 :
1.3 總結
不分離項目中我們做鑒權很容易,采用過濾器、攔截器(基於session存儲)或者apache shiro、spring security,比較容易實現。但是前后端分離就稍微有點麻煩了,下面給出解決方案。
2.應對方案
2.1 前后端分離鑒權采用JWT
Json web token (JWT), 是為了在網絡應用環境間傳遞聲明而執行的一種基於JSON的開放標准((RFC 7519).該token被設計為緊湊且安全的,特別適用於分布式站點的單點登錄(SSO)場景。JWT的聲明一般被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便於從資源服務器獲取資源,也可以增加一些額外的其它業務邏輯所必須的聲明信息,該token也可直接被用於認證,也可被加密。
傳統的session認證
我們知道,http協議本身是一種無狀態的協議,而這就意味着如果用戶向我們的應用提供了用戶名和密碼來進行用戶認證,那么下一次請求時,用戶還要再一次進行用戶認證才行,因為根據http協議,我們並不能知道是哪個用戶發出的請求,所以為了讓我們的應用能識別是哪個用戶發出的請求,我們只能在服務器存儲一份用戶登錄的信息,這份登錄信息會在響應時傳遞給瀏覽器,告訴其保存為cookie,以便下次請求時發送給我們的應用,這樣我們的應用就能識別請求來自哪個用戶了,這就是傳統的基於session認證。
但是這種基於session的認證使應用本身很難得到擴展,隨着不同客戶端用戶的增加,獨立的服務器已無法承載更多的用戶,而這時候基於session認證應用的問題就會暴露出來
於session認證所顯露的問題
Session: 每個用戶經過我們的應用認證之后,我們的應用都要在服務端做一次記錄,以方便用戶下次請求的鑒別,通常而言session都是保存在內存中,而隨着認證用戶的增多,服務端的開銷會明顯增大。
擴展性: 用戶認證之后,服務端做認證記錄,如果認證的記錄被保存在內存中的話,這意味着用戶下次請求還必須要請求在這台服務器上,這樣才能拿到授權的資源,這樣在分布式的應用上,相應的限制了負載均衡器的能力。這也意味着限制了應用的擴展能力。
CSRF: 因為是基於cookie來進行用戶識別的, cookie如果被截獲,用戶就會很容易受到跨站請求偽造的攻擊。
基於token的鑒權機制
基於token的鑒權機制類似於http協議也是無狀態的,它不需要在服務端去保留用戶的認證信息或者會話信息。這就意味着基於token認證機制的應用不需要去考慮用戶在哪一台服務器登錄了,這就為應用的擴展提供了便利。
流程上是這樣的:
- 用戶使用用戶名密碼來請求服務器
- 服務器進行驗證用戶的信息
- 服務器通過驗證發送給用戶一個token
- 客戶端存儲token,並在每次請求時附送上這個token值
- 服務端驗證token值,並返回數據
這個token必須要在每次請求時傳遞給服務端,它應該保存在請求頭里, 另外,服務端要支持CORS(跨來源資源共享)
策略,一般我們在服務端這么做就可以了Access-Control-Allow-Origin: *
。
2.2 接口隱藏涉密信息
采用java棧做后台接口,經常會用到orm框架,一個查詢就把一個實體查出來返回前端,難免會把涉密字段帶出來返回前端。應對方案:
2.3 sql注入、xss、webshell注入
暴露在互聯網上難免被掃描攻擊,黑客利用掃描攻擊掃應用的版本,嘗試各種注入。應對方案:
- 攔截器或過濾器,監測Http請求中有敏感字符的比如:cmd、eval、shell等,就攔截直接返回拒絕訪問。
- 如果某個ip一直掃描瘋狂探測並且請求中帶有敏感字符,就把該ip放入黑名單,黑名單可以用緩存實現、存放禁用Ip,建議可以用redis存儲。
具體實現可以看我的文章《nodejs http-proxy 開發反向代理服務器,防火牆,過濾常見的web滲透》
《spring 防止SQL注入的攔截器》
2.4 越權訪問他人信息
不要信任前端的參數,記得做后台權限判斷
比如我們的訂單id是數字類型的,黑客可以用工具去循環遍歷,獲取所有用戶的訂單信息,這樣就很不安全。
這個時候后台要做權限判斷,根據前端傳的訂單id和token信息,判斷該訂單是否是token對應用戶的訂單,如果不是就不返會信息。
2.5 短信轟炸
針對短信炸彈漏洞,建議限制每個手機號的每日發送次數,每個ip最大發送次數,限制 每個手機號發送的時間間隔,以及應具有頁面圖片驗證碼、IP訪問次數限制功能。實現方式可以采用redis過期緩存。
2.6 避免報錯信息返回前端
異常信息可能把ip端口號之類的返回到前端了,這樣會給黑客滲透留下提示,怎么辦吶?
- 采用攔截器、aop過濾返回信息,如果攜帶有Exception關鍵字,就去掉報錯信息。
參考
什么是 JWT -- JSON WEB TOKEN https://www.jianshu.com/p/576dbf44b2ae
總結不易歡迎在看或轉發,更多精彩關注微信公眾號【lovepythoncn】
**