JAVA开发常见安全问题:密码修改(无需原密码)
·
专栏链接
一、数据的校验
二、认证与授权
三、Cookie与会话管理
四、错误处理
五、日志安全
六、未验证的重定向
二、认证与授权:密码修改(无需原密码)
漏洞描述:
正常的修改密码都是需要在最后一步验证原密码是否正确, 如果正确才去修改密码。尤其是 Ajax 技术的出现,如今很多程序在修改密码的时候,都喜欢在用户输入原密码之后,先用 ajax 异步的方式去数据库中查询一下是否正确,如果正确才允许用户继续提交密码修改的请求。可往往程序员在最后一步的时候忘了再次校验原密码的操作。
检测方法:
检查对密码的验证是否采用 Ajax 方式单独去校验。检查修改密码的最后步骤是否再次验证原密码。
不合规的代码示例:
/**
* 检测原密码是否正确
*@return
*@throws Exception
*/
public String checkOldPwd() throws Exception{
//从页面得到原密码
String pwd = request.getParameter(""oldPwd"");
//实例密码处理类
MD5 md5 = new MD5();
//登录者的工号
String userNo =((SessionVO)session.get(ConstVar.SESSIONVO)).getLoginNo ();
//得到登录者信息
OpLoginmsgDict loginInfo =rightManageService.getLoginInfo(userNo);
String oldPwd = md5.getMD5ofStr(pwd);
//生成上下文
HttpServletResponse response =ServletActionContext.getResponse();
response.setContentType(""text/html; charset=GB2312"");
response.setHeader(""Cache-Control"", ""no-cache"");
PrintWriter out=response.getWriter();
//密码比较处理
if(oldPwd.equals(loginInfo.getLoginPassword())){
out.print(""{success:true,message:'原密码正确!'}"");
}else{
out.print(""{success:false,message:'原密码不正确!'}"");
}
out.close();
return null;
}
/***
*修改密码
*@return
*@throws Exception
*/
public String changePwd() throws Exception {
HttpServletResponse response = ServletActionContext.getResponse();
// 登录者的工号
String userNo = ((SessionVO) session.get(ConstVar.SESSIONVO)).getLoginNo();
String pwdDay = ""90"";
response.setContentType(""text/html; charset=GB2312"");
response.setHeader(""Cache-Control"", ""no-cache"");
PrintWriter out = null; String newPwd =
request.getParameter(""longinPwd"");
if (!CommonUtils.isEmpty(newPwd)) {
boolean isValid = CommonUtils.isPasswordValid(newPwd);
if (isValid == false) {
out = response.getWriter();
out.print(""{success:false,message:'密码长度至少 8 位或以上,密码由数字及字母混合组成,其中必须同时包含大小写字母;'}"");
out.close();
return null;
}
}
boolean flag = rightManageService.checkPwdRepeatUse(userNo, newPwd);
if (flag == false) {
out = response.getWriter();
out.print(""{success:false,message:'不得使用最近5 次以内重复的密码'}"");
out.close();
return null;
}
rightManageService.changePwd(newPwd, userNo,...
不合规说明:
此处密码修改过程中,前端首先采用 Ajax 方式调用了checkOldPwd 方法,如果返回的 json 数据中 success 的值为 true 则表示原密码输入正确,然后进入下一步(修改密码),但由于修改密码的方法中未再次判断原密码是否正确。恶意用户不需要原密码即可修改密码。
合规的代码示例:
/***
*修改密码
*@return
*@throws Exception
*/
public String changePwd() throws Exception { HttpServletResponse response =
ServletActionContext.getResponse();
// 登录者的工号
String userNo = ((SessionVO) session.get(ConstVar.SESSIONVO)).getLoginNo();
String pwdDay = ""90"";
response.setContentType(""text/html; charset=GB2312"");
response.setHeader(""Cache-Control"", ""no-cache"");
String newPwd = request.getParameter(""longinPwd"");
//从页面得到原密码
String oldPwd = request.getParameter(""oldPwd"");
//实例密码处理类
MD5 md5 = new MD5();
//得到登录者信息
OpLoginmsgDict loginInfo =
rightManageService.getLoginInfo(userNo);
oldPwd = md5.getMD5ofStr(oldPwd);
PrintWriter out=response.getWriter();
//密码比较处理
if(oldPwd.equals(loginInfo.getLoginPassword())){
if (!CommonUtils.isEmpty(newPwd)) {
boolean isValid = CommonUtils.isPasswordValid(newPwd);
if (isValid == false) {
out.print(""{success:false,message:'密码长度至少 8 位或以上,密码由数字及字母混合组成,其中必须同时包含大小写字母;'}"");
out.close(); return null;
}
}
boolean flag = rightManageService.checkPwdRepeatUse(userNo, newPwd);
if (flag == false) {
out = response.getWriter();
out.print(""{success:false,message:'不得使用最近5 次以内重复的密码'}"");
out.close();
return null;
}
rightManageService.changePwd(newPwd, userNo,...
合规说明:
在修改密码操作的 changePwd 方法中增加对原密码的判断。
更多推荐




所有评论(0)