横向越权:攻击者尝试访问与他拥有相同权限的用户的资源。
纵向越权:一个低级别攻击者尝试访问高级别用户的资源。
例:
如果一个用户忘记密码,那么考虑一下具体的业务场景应该是什么样的。
第一步:用户首先会对个人密码提示问题,或手机密保等方式进行校验。
如果第一步执行成功,这时则会输入新的密码、用户名来更改用户的密码。
但是如果这个人通过校验之后,直接使用接口的调用的方式随意修改成其它的用户名与密码。
如果修改的是相同访问权限的用户则造成了横向越权,如果是访问是高级用户(比如管理员root)则会造成纵向越权。 解决:用户处理忘记密码时,需要回传一个forgetToken,并设置其销毁时间。 在更改密码的时首先校验forgetToken。
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.createByErrorMessage("问题的答案错误");
}
public ServerResponse<String> forgetResetPassword(String username,String passwordNew,String forgetToken){
if(org.apache.commons.lang3.StringUtils.isBlank(forgetToken)){
return ServerResponse.createByErrorMessage("参数错误,token需要传递");
}
ServerResponse validResponse = this.checkValid(username,Const.USERNAME);
if(validResponse.isSuccess()){
//用户不存在
return ServerResponse.createByErrorMessage("用户不存在");
}
String token = TokenCache.getKey(TokenCache.TOKEN_PREFIX+username);
if(org.apache.commons.lang3.StringUtils.isBlank(token)){
return ServerResponse.createByErrorMessage("token无效或者过期");
}
if(org.apache.commons.lang3.StringUtils.equals(forgetToken,token)){
String md5Password = MD5Util.MD5EncodeUtf8(passwordNew);
int rowCount = userMapper.updatePasswordByUsername(username,md5Password);
if(rowCount > 0){
return ServerResponse.createBySuccessMessage("修改密码成功");
}
}else{
return ServerResponse.createByErrorMessage("token错误,请重新获取重置密码的token");
}
return ServerResponse.createByErrorMessage("修改密码失败");
}
复制代码