云计算百科
云计算领域专业知识百科平台

JAVA开发常见安全问题:登录尝试次数限制功能失效

专栏链接

一、数据的校验

  • SQL注入
  • 命令注入
  • 跨站脚本
  • 任意文件上传
  • 任意文件下载
  • 任意文件删除
  • 任意文件读取与写入
  • Iframe 框架钓鱼
  • 负值支付漏洞
  • 二、认证与授权

  • 密码修改(无需原密码)
  • 密码策略不足
  • 用户名密码(敏感信息)明文传输
  • 验证码可重复利用
  • 缺少验证码功能
  • 用户名枚举(用户名和密码单独验证)
  • 认证与授权:登录尝试次数限制功能失效

    漏洞描述:

    作为登录页面防护措施的一种,开发人员注重的是功能能不能用,而非安不安全,思维上比较常规,导致在非常规情况下这种防护却形同虚设。

    检测方法:

    检查程序中是否将“登录错误次数”保存在某个局部变量中。检查该功能所防护的 URL 是否正确,是否存在多个登录的URL。

    不合规的代码示例:

    //登录页面代码:
    <form id="loginForm" method="post" action="${root}/j_security_check">
    <p class="id error"><span><input id="j_username" name="j_username"
    onKeyDown="onkeydownn();" type="text" autocomplete="off"/></span></p>
    <p><span><input id="j_password" name="j_password" onKeyDown="onkeydownn();" type="password" autocomplete="off"/></span></p>
    <p>
    <span><input id="j_vc" name="j_vc" onKeyDown="onkeydownn();" type="text" autocomplete="off"/></span>
    <span><img src="${ctx }/verifycode.jsp" name="verifycode" id="verifycode" onClick="javascript:randomidbetter(this)"/></span>
    </p>
    </form>
    用户登录的拦截器代码如下:
    private boolean bfaCheck(HttpServletRequest request, HttpServletResponse response) {
    String requestUri = request.getRequestURI();
    String query = request.getQueryString();
    String ip = request.getRemoteAddr();
    BruteForceAttackInfo info = bfaInfos.get(ip);
    Date now = new Date();
    if (info != null && info.getLockTime() != null &&
    now.getTime() info.getLockTime().getTime() <= bfaLockTime) {
    logger.info("监测到登录失败次数过多,将被禁止访问5 分钟. IP:{}", ip);
    request.setAttribute("err", "拒绝访问:登录失败次数过多,禁止访问 5 分钟");
    response.setHeader("err", "iplock");
    return false;
    }

    if (!Util.isEmpty(requestUri) && requestUri.endsWith("/login.action") && !Util.isEmpty(query) && query.equals("error=1")) {
    if (info != null) {
    if (info.getTryStartTime() != null) {
    if (now.getTime() info.getTryStartTime().getTime() <= bfaTime) {
    int tCount = info.getTryCount();
    if (tCount <= bfaAllowNumber) {
    info.setTryCount(++tCount);
    bfaInfos.put(ip, info);
    return true;
    } else {
    info.setLockTime(now);
    bfaInfos.put(ip, info);
    logger.info("监测到登录失败次数过多,将被禁止访问 5 分钟. IP:{}", ip);
    request.setAttribute("err", "拒绝访问:登录失败次数过多,禁止访问 5 分钟");
    response.setHeader("err", "iplock");
    return false;
    }
    } else {
    info.setTryStartTime(now);
    info.setTryCount(1);
    info.setLockTime(null);
    bfaInfos.put(ip, info);
    return true;
    }
    } else {
    info.setTryStartTime(now);
    info.setTryCount(1);
    bfaInfos.put(ip, info);
    return true;
    }
    } else {
    BruteForceAttackInfo newTry = new
    BruteForceAttackInfo(now, 1, null);
    bfaInfos.put(ip, newTry);
    return true;
    }
    }
    return true;
    }

    不合规说明:

    用户登录页面提交后台处理的 URL 为/j_security_check, 身份认证失败之后跳转的路径为/login.action。此拦截器只是针对失败之后的路径做登录尝试次数的限制,而对 /j_security_check 却未做同样的处理。导致此拦截器形同虚设。

    合规的代码示例:

    //登录页面代码:
    <form id="loginForm" method="post" action="${root}/j_security_check">
    <p class="id error"><span><input id="j_username" name="j_username"
    onKeyDown="onkeydownn();" type="text" autocomplete="off"/></span></p>
    <p><span><input id="j_password" name="j_password" onKeyDown="onkeydownn();" type="password" autocomplete="off"/></span></p>
    <p>
    <span><input id="j_vc" name="j_vc" onKeyDown="onkeydownn();" type="text" autocomplete="off"/></span>
    <span><img src="${ctx }/verifycode.jsp" name="verifycode" id="verifycode" onClick="javascript:randomidbetter(this)"/></span>
    </p>
    </form>
    //用户登录的拦截器代码如下:
    private boolean bfaCheck(HttpServletRequest request,
    HttpServletResponse response) {
    String requestUri = request.getRequestURI();
    String query = request.getQueryString();
    String ip = request.getRemoteAddr();
    BruteForceAttackInfo info = bfaInfos.get(ip);
    Date now = new Date();
    if (info != null && info.getLockTime() != null &&
    now.getTime() info.getLockTime().getTime() <= bfaLockTime) {
    logger.info("监测到登录失败次数过多,将被禁止访问5 分钟. IP:{}", ip);
    request.setAttribute("err", "拒绝访问:登录失败次数过多,禁止访问 5 分钟");
    response.setHeader("err", "iplock");
    return false;
    }
    if (!Util.isEmpty(requestUri) && ((requestUri.endsWith("/login.action")
    && !Util.isEmpty(query) && query.equals("error=1")) ||requestUri.endsWith("/j_security_check"))) {
    if (info != null) {
    if (info.getTryStartTime() != null) {
    if (now.getTime() info.getTryStartTime().getTime() <= bfaTime) {
    int tCount = info.getTryCount();
    if (tCount <= bfaAllowNumber) {
    info.setTryCount(++tCount);
    bfaInfos.put(ip, info);
    return true;
    } else {
    info.setLockTime(now);
    bfaInfos.put(ip, info);
    logger.info("监测到登录失败次数过多,将被禁止访问 5 分钟. IP:{}", ip);
    request.setAttribute("err", "拒绝访问:登录失败次数过多,禁止访问 5 分钟");
    response.setHeader("err", "iplock");
    return false;
    }
    } else {
    info.setTryStartTime(now);
    info.setTryCount(1);
    info.setLockTime(null);
    bfaInfos.put(ip, info);
    return true;
    }
    } else {
    info.setTryStartTime(now);
    info.setTryCount(1);
    bfaInfos.put(ip, info);
    return true;
    }
    } else {
    BruteForceAttackInfo newTry = new
    BruteForceAttackInfo(now, 1, null);
    bfaInfos.put(ip, newTry);
    return true;
    }
    }
    return true;
    }

    合规说明:

    在拦截器中增添了对登录提 url(/j_security_check) 的登录错误次数限制。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » JAVA开发常见安全问题:登录尝试次数限制功能失效
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!