橫向越權:橫向越權指的是攻擊者嘗試訪問與他擁有相同權限的用戶的資源
縱向越權:縱向越權指的是一個低級別攻擊者嘗試訪問高級別用戶的資源
對於縱向越權,我們可以通過設置用戶角色,為不同的角色提供不同的權限來避免。
對於橫向越權,就比較麻煩了,橫向越權可能出現的場景有:在用戶忘記密碼重置密碼時,回答對了問題進入密碼重置階段時,如果知道其他用戶的用戶名,很容易改變此用戶的密碼,然后就可以進行越權訪問了。
這種情況下為了防止橫向越權,我們可以使用緩存來進行輔助,當問題回答正確時,我們在緩存中存儲一對由用戶名和一個唯一的數字組成的數據,然后返回放入的唯一數據。在重置密碼時我們的參數不僅需要用戶名和密碼還需要前面生成的唯一數字,根據用戶名在緩存中取出對應的數字,如果取出的數字和參數中傳入的想等,則證明重置的當前用戶的密碼,否則不是,且不予以重置。
重置密碼回答問題
public ServerResponse<String> checkAnswer(String username, String question, String answer){ int resultCount = userMapper.checkAnswer(username, question, answer); if(resultCount>0){ //說明問題及問題答案是用戶的,並且是正確的 String forgetToken = UUID.randomUUID().toString(); //放入緩存 TokenCache.setKey(TokenCache.TOKEN_PREFIX+username, forgetToken); return ServerResponse.createBySuccess(forgetToken); } return ServerResponse.createByError("用戶答案錯誤"); }
重置密碼
public ServerResponse<String> forgetResetPassword(String username, String passwordNew, String forgetToken){ if(StringUtils.isBlank(forgetToken)){ return ServerResponse.createByError("參數錯誤,Token需要傳遞"); } ServerResponse validResponse = this.checkValid(username, Const.USERNAME); if(validResponse.isSuccess()){ return ServerResponse.createByError("用戶不存在"); } //使用Cache而不使用session是因為當應用程序結束時,如果緩存的失效時間未到,則下次啟動程序時,緩存數據依然存在 //但是Seesion中的數據只保存在一次會話中,session容易丟失不夠安全,而Cache不會出現這種問題 String token = TokenCache.getKey(TokenCache.TOKEN_PREFIX+username); if(StringUtils.isBlank(token)){ ServerResponse.createByError("token無效或過期"); } if(StringUtils.equals(token, forgetToken)){ String md5Password = MD5Util.MD5EncodeUtf8(passwordNew); int resultCount = userMapper.updatePasswordByUsername(username, md5Password); if(resultCount>0){ return ServerResponse.createBySuccess("修改密碼成功"); } }else{ return ServerResponse.createByError("token錯誤,請重新獲取修改密碼的token"); } return ServerResponse.createByError("密碼更新失敗");