横向越权:横向越权指的是攻击者尝试访问与他拥有相同权限的用户的资源
纵向越权:纵向越权指的是一个低级别攻击者尝试访问高级别用户的资源
对于纵向越权,我们可以通过设置用户角色,为不同的角色提供不同的权限来避免。
对于横向越权,就比较麻烦了,横向越权可能出现的场景有:在用户忘记密码重置密码时,回答对了问题进入密码重置阶段时,如果知道其他用户的用户名,很容易改变此用户的密码,然后就可以进行越权访问了。
这种情况下为了防止横向越权,我们可以使用缓存来进行辅助,当问题回答正确时,我们在缓存中存储一对由用户名和一个唯一的数字组成的数据,然后返回放入的唯一数据。在重置密码时我们的参数不仅需要用户名和密码还需要前面生成的唯一数字,根据用户名在缓存中取出对应的数字,如果取出的数字和参数中传入的想等,则证明重置的当前用户的密码,否则不是,且不予以重置。
重置密码回答问题
public ServerResponsecheckAnswer(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);returnServerResponse.createBySuccess(forgetToken);
}return ServerResponse.createByError("用户答案错误");
}
重置密码
public ServerResponseforgetResetPassword(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("密码更新失败");