漏洞解决方案-短信炸弹攻击

一、前置知识

短信炸弹攻击,就是通过把发送短信验证码的报文截获后进行重放造成的攻击。
威胁描述:
如果短信炸弹攻击成功,攻击者可以向该手机号一直不停的发送短信,不但因短信过多发送造成经济损失,甚至会使短信系统崩溃,无法正常提供服务。
涉及功能点:
任何涉及短信验证码发送的功能点,如用户注册、登录、转账等功能。

二、修复方案

  1. 前端控制,通过图形验证码的验证,如果验证不通过则不允许发送短信;
  2. 其次为防止类似httpclient工具直接请求没有session的情况,进行session有无判断,如果没有session信息则不允许发送短信;
  3. 除此之外,再从session、ip、手机号、客户号四个方面请求频率和单位时间请求次数两个角度进行限制,防止短信炸弹,具体如下:
    1)session:
    a.同一sessionId两次的请求时间间隔不应小于设定值(建议请求时间间隔为60s);
    b.同一sessionId的单位时间请求次数不应大于设定值(建议10分钟时间内请求次数不能超过8次);
    2)ip:
    同一ip单位时间请求次数不应大于设定值(考虑到局域网问题,建议只限定10分钟时间内请求次数不能超过200次);
    3)手机号:
    a.同一手机号两次的请求时间间隔不应小于设定值(建议请求时间间隔为60s);
    b.同一手机号的单位时间请求次数不应大于设定值(建议10分钟时间内请求次数不能超过5次);
    4)客户号(针对如个网跳转注册直销等已知客户号的场景):
    a.同一客户号两次的请求时间间隔不应小于设定值(建议请求时间间隔为60s);
    b.同一客户号的单位时间请求次数不应大于设定值(建议10分钟时间内请求次数不能超过5次);

三、代码参考

安全开发实例:

  1. 通过session id防护:

    #!java
    
    String sessionId = session.getId();   //判断同一sessionId请求时间间隔是否小于设定间隔,防止恶意攻击
    Long preReqTime4Session = reqTimeMap4Session.get(sessionId);    //上次请求时间
    Long curReqTime4Session = System.currentTimeMillis();   //本次请求时间
    AtomicInteger errorTimes4Session = reqErrorMap4Session.get(sessionId); //频繁调用累计次数
    if(preReqTime4Session!=null) {
    	//频率校验
    	if(curReqTime4Session-preReqTime4Session < refuseInterval) {
    		log.error("session_attack: " + sessionId + "===curReqTime-preReqTime < refuseInterval==");
    		isError = true;
    	} else {
    		//总次数校验
    		if(errorTimes4Session != null && errorTimes4Session.get() >= sessionTimes) {
    			log.error("session_attack: " + sessionId + "===errorTimes==" + errorTimes4Session);
    			isError = true;
    		}
    	}
    } else {
    	if(errorTimes4Session != null) {
    		reqErrorMap4Session.remove(sessionId);
    	}
    }
    
  2. 通过IP防护:

    #!java
    
    String ipAddress = getIp(context);   //判断同一IP请求时间间隔是否小于设定间隔,防止恶意攻击
    Long preReqTime = reqTimeMap.get(ipAddress);    //上次请求时间
    Long curReqTime = System.currentTimeMillis();   //本次请求时间
    AtomicInteger errorTimes = reqErrorMap.get(ipAddress); //频繁调用累计次数
    if(preReqTime!=null) {
    	//次数校验
    	if(errorTimes != null && errorTimes.get() >= ipTimes) {
    		log.error("ip_attack: " + ipAddress + "===errorTimes==" + errorTimes);
    		isError = true;
    	}
    } else {
    	if(errorTimes != null) {
    		reqErrorMap.remove(ipAddress);
    	}
    }
    
  3. 通过手机号防护:

    #!java
    
    Long preReqTime4Phone = reqTimeMap4Phone.get(mobilePhone);    //上次请求时间
    Long curReqTime4Phone = System.currentTimeMillis();   //本次请求时间
    AtomicInteger errorTimes4Phone = reqErrorMap4Phone.get(mobilePhone); //频繁调用累计次数
    if(preReqTime4Phone!=null) {
    	//频率校验
    	if(curReqTime4Phone-preReqTime4Phone < refuseInterval) {
    		log.error("phone_attack: " + mobilePhone + "===curReqTime-preReqTime < refuseInterval==");
    		isError = true;
    	} else {
    		//次数校验
    		if(errorTimes4Phone != null && errorTimes4Phone.get() >= mobileTimes) {
    			log.error("phone_attack: " + mobilePhone + "===errorTimes==" + errorTimes4Phone);
    			isError = true;
    		}
    	}
    } else {
    	if(errorTimes4Phone != null) {
    		reqErrorMap4Phone.remove(mobilePhone);
    	}
    }
    
  4. 通过客户号防护:

    #!java
    
    Long preReqTime4CifNo = reqTimeMap4CifNo.get(cifNo4TokenImg);    //上次请求时间
    Long curReqTime4CifNo = System.currentTimeMillis();   //本次请求时间
    AtomicInteger errorTimes4CifNo = reqErrorMap4CifNo.get(cifNo4TokenImg); //频繁调用累计次数
    if(preReqTime4CifNo!=null) {
    	//频率校验
    	if(curReqTime4CifNo-preReqTime4CifNo < refuseInterval) {
    		log.error("CifNo_attack: " + cifNo4TokenImg + "===curReqTime-preReqTime < refuseInterval==");
    		isError = true;
    	} else {
    		//次数校验
    		if(errorTimes4CifNo != null && errorTimes4CifNo.get() >= cifNoTimes) {
    			log.error("CifNo_attack: " + cifNo4TokenImg + "===errorTimes==" + errorTimes4CifNo);
    			isError = true;
    		}
    	}
    } else {
    	if(errorTimes4CifNo != null) {
    		reqErrorMap4CifNo.remove(cifNo4TokenImg);
    	}
    }
    

关注公众号,一起分享实用安全技术,关注安全最新事件,记录工作常见问题,吐槽生活真心操蛋。
在这里插入图片描述

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值