一、短信通道防盗刷方案

一、使用安全图形验证码,增加识别难度,防止通过自动化工具进行攻击请求;
规则:使用手滑动形式的验证码。
二、限制每个手机号的发送次数;
规则:每个手机号每天最多只能发10条短信;
三、单Ip的请求次数限制,防止攻击者对服务器进行大量无效请求(在图形验证码未破解的情况下,自动化工具行程错误请求),增加服务器负担;
规则:限制单IP每天请求次数不能超过10次。
四、单用户动态短信请求间隔时长限制,防止对单个用户形成手工攻击,防止图形验证码失效后对用户形成大量攻击;
规则:单用户请求短信时间间隔为“60秒”;
五、增加IP黑名单库,在黑名单库的Ip永久不能获取验证码;管理员可以手动添加IP黑名单,可以手动删除黑名单;
黑名单规则:
1)同一号码在同一天内发送超过10条短信;
2)同一IP在1分钟内出现3次以上;
3)同一IP在30分钟内超过5次以上;
4)同一IP在60分钟内出现10次以上 ;
5)同一IP在48*60内出现20以上 ;

以上为方案参考

二、参数配置短信策略

三、代码实现

技术方案:
1.将参数存入redis缓存,每次从缓存中获取参数;
2.短信间隔60秒用redis缓存,有效期设置为60秒
3.请求次数存入redis,每次请求加1,到达上限则限制发送短信

====短信策略Service类

package com.shijie.box.service;import com.shijie.box.db.util.StringUtil;
import com.shijie.box.util.IpUtil;
import com.shijie.box.vo.ApiResult;
import com.shijie.box.vo.SmsFangweiSendRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;/*** 短信发送策略  wy* 2020/7/29*/
@Service
public class SmsPolicyService {private static final Logger logger = LoggerFactory.getLogger(SmsPolicyService.class);private static final String MOBILE_PROFIX = "SMS_MOBILE_";//短信手机号缓存类型private static final String IP_PROFIX = "SMS_IP_";//短信手机号缓存类型private static final String SMSTIME = "SMSTIME_";//短信手机号缓存有效时长private static final String SMS_IP_BLACK_LIST = "SMS_IP_BLACK_LIST";//【短信策略】IP黑名单,以";"间隔private static final String SMS_IP_WHITE_LIST = "SMS_IP_WHITE_LIST";//【短信策略】IP白名单,当前IP不做任何策略限制,以“;”间隔private static final String SMS_TIME_SPACING = "SMS_TIME_SPACING";//【短信策略】单用户(IP)请求短信时间间隔为“60秒”private static final String SMS_COUNT_PER_IP = "SMS_COUNT_PER_IP";//【短信策略】限制单IP每天请求次数不能超过10次private static final String SMS_COUNT_PER_MOBILE = "SMS_COUNT_PER_MOBILE";//【短信策略】每个手机号每天最多只能发10条短信@Autowiredcom.shijie.box.db.util.RedisUtil redisUtil;@Resourcecom.shijie.box.db.dao.SxbSysParameterMapper SxbSysParameterMapper;/*** 短信发送策略* @param request* @return*/public ApiResult policy(SmsFangweiSendRequest parameter, HttpServletRequest request) {ApiResult rest=new ApiResult("0000","短信策略通过");String ipAddr = IpUtil.getIpAddr(request);String whiteList = redisUtil.get(SMS_IP_WHITE_LIST);//ip白名单//如果缓存中未存短信策略,则开始缓存if(StringUtil.isEmpty(whiteList)){refreshSMSPolicy();whiteList = redisUtil.get(SMS_IP_WHITE_LIST);//ip白名单}//=======如果是IP白名单,直接通过策略===============//if(whiteList.indexOf(ipAddr)>=0){logger.info("[短信策略]请求IP:"+ipAddr+",IP白名单放行");return rest;}//===========如果ip黑名单,则直接返回,不通过策略===============//String blackList = redisUtil.get(SMS_IP_BLACK_LIST);//ip黑名单if(blackList.indexOf(ipAddr)>=0){logger.info("[短信策略]请求IP:"+ipAddr+",IP黑名单,做拦截");return new ApiResult("0001","未发送,当前ip:"+ipAddr+"已被限制发送短信,请联系管理员");}//================【短信策略】限制单IP每天请求次数不能超过10次================//int SMSIpCount = Integer.parseInt(redisUtil.get(SMS_COUNT_PER_IP));String ipCountKey = IP_PROFIX+ipAddr;int ipCount = StringUtil.isEmpty(redisUtil.get(ipCountKey))?0: Integer.parseInt(redisUtil.get(ipCountKey));if(ipCount>=SMSIpCount){logger.info("[短信策略]请求IP:"+ipAddr+",当前IP,今日发送短信次数过多,已超过"+SMSIpCount+"次");return new ApiResult("0002","当前IP今日发送短信次数过多,已超过"+SMSIpCount+"次");}//================【短信策略】每个手机号每天最多只能发10条短信================//int SMSMobileCount = Integer.parseInt(redisUtil.get(SMS_COUNT_PER_MOBILE));String mobileCountKey = MOBILE_PROFIX+parameter.getMobile();int mobileCount = StringUtil.isEmpty(redisUtil.get(mobileCountKey))?0: Integer.parseInt(redisUtil.get(mobileCountKey));if(mobileCount>=SMSMobileCount){logger.info("[短信策略]请求IP:"+ipAddr+",当前手机号"+parameter.getMobile()+",今日发送短信次数过多,已超过"+SMSMobileCount+"次");return new ApiResult("0002","当前手机号今日发送短信次数过多,已超过"+SMSMobileCount+"次");}//================【短信策略】单用户(IP)请求短信时间间隔为“60秒”============//String rediskeyIp = SMSTIME+ipAddr;Long smsTimeSpacing = Long.parseLong(redisUtil.get(SMS_TIME_SPACING));//【短信策略】单用户(IP)请求短信时间间隔为“60秒”if(!StringUtil.isEmpty(redisUtil.get(rediskeyIp))){logger.info("[短信策略]请求IP:"+ipAddr+",请勿频繁请求,再次获取请间隔");return new ApiResult("0002","请勿频繁请求,再次获取请间隔"+smsTimeSpacing+"秒");}//================【短信策略】限制单IP每天请求次数不能超过10次===当前为修改缓存中的次数=============//if(ipCount==0){redisUtil.setEx(ipCountKey,++ipCount+"",86400, TimeUnit.SECONDS);//1天}else{redisUtil.setEx(ipCountKey,++ipCount+"",redisUtil.getExpire(ipCountKey), TimeUnit.SECONDS);}//================【短信策略】每个手机号每天最多只能发10条短信====当前为修改缓存中的次数============//if(mobileCount==0){redisUtil.setEx(mobileCountKey,++mobileCount+"",86400, TimeUnit.SECONDS);//1天}else{redisUtil.setEx(mobileCountKey,++mobileCount+"",redisUtil.getExpire(mobileCountKey), TimeUnit.SECONDS);}//================【短信策略】单用户(IP)请求短信时间间隔为“60秒”====当前为修改缓存中的秒数========////设置当前ip再次发送短信时间间隔为60秒redisUtil.setEx(rediskeyIp,ipAddr,smsTimeSpacing, TimeUnit.SECONDS);return rest;}/*** 刷新短信发送策略缓存*/public void refreshSMSPolicy(){//设置缓存有效期为2天,两天后发送短信时候,会再次加载此缓存redisUtil.setEx(SMS_IP_BLACK_LIST,SxbSysParameterMapper.selectByPrimaryKey(SMS_IP_BLACK_LIST).getpValue().trim(),2, TimeUnit.DAYS);redisUtil.setEx(SMS_IP_WHITE_LIST,SxbSysParameterMapper.selectByPrimaryKey(SMS_IP_WHITE_LIST).getpValue().trim(),2, TimeUnit.DAYS);redisUtil.setEx(SMS_TIME_SPACING,SxbSysParameterMapper.selectByPrimaryKey(SMS_TIME_SPACING).getpValue().trim(),2, TimeUnit.DAYS);redisUtil.setEx(SMS_COUNT_PER_IP,SxbSysParameterMapper.selectByPrimaryKey(SMS_COUNT_PER_IP).getpValue().trim(),2, TimeUnit.DAYS);redisUtil.setEx(SMS_COUNT_PER_MOBILE,SxbSysParameterMapper.selectByPrimaryKey(SMS_COUNT_PER_MOBILE).getpValue().trim(),2, TimeUnit.DAYS);}
}

====短信发送Controller

@Controller
@RequestMapping("/sms/fangwei")
@Api("短信相关接口")
public class SmsFangWeiApi {@Autowiredprivate HttpServletRequest request;@Autowiredprivate  SmsFangweiService service;@PostMapping("/send")@ApiOperation("发送短信api")@ResponseBodypublic ApiResult<String> send(@RequestBody  SmsFangweiSendRequest  SmsFangweiSendRequest) {ApiResult<String>   rest= service.send(SmsFangweiSendRequest,request) ;return rest;}
}

=====发送短信service

@Service
public class SmsFangweiService {private static final Logger logger = LoggerFactory.getLogger(SmsFangweiService.class);@Autowiredprivate SmsPolicyService SmsPolicyService;public  String send(SmsFangweiSendRequest request, HttpServletRequest httpServletRequest) {logger.info("进入短信发送策略{}","短信策略参数配置");//=========短信策略,0000代码策略通过================//ApiResult policy = SmsPolicyService.policy(request, httpServletRequest);//如果通过策略则走发短信流程if("0000".equals(policy.getError_code())) {//发送短信方法sendSMS();}else{logger.info("【未通过短信策略】,"+policy.getMessage());}if(!"0000".equals(policy.getError_code())){return "error";}else {return "success";}}
}

代码中用到的两个IPUtil和RedisUtil下载链接:
链接:https://pan.baidu.com/s/1KE0_wXvbqaK2hQR0Ikc_gg
提取码:4ujn

以上如果获取手机流量的IP不准确,可以参考文章:
java获取手机IP地址不准确解决
https://blog.csdn.net/wangyue23com/article/details/107764209

短信通道防盗刷,短信发送策略相关推荐

  1. 听云短信接口安全测试,你的短信接口到底有多危险,可能瞬间损失过万,短信接口防盗刷测试

    – "隐患险于明火,防范胜于救灾,责任重于泰山" 安全问题不容忽视,不要亡羊补牢! 前言 一丶找到对外短信接口 二丶分析外部防御措施 三丶查看请求报文 四丶分析测试 1. 直接在浏 ...

  2. 安全测试:孔夫子旧书网短信接口安全测试,你的短信接口到底有多危险,可能瞬间损失过万,短信接口防盗刷测试

    – "隐患险于明火,防范胜于救灾,责任重于泰山" 安全问题不容忽视,不要亡羊补牢! 前言 一丶找到对外短信接口 二丶分析外部防御措施 三丶查看请求报文 四丶分析测试 1. 分析测试 ...

  3. 商家平台短信防盗刷解决方案

    很多商家平台都有对接短信功能来验证用户的真实性,这个本来是一个很正常的业务需要,但是却被一些有心人用程序进行频繁请求发送,造成短信被恶意发送,那么短信防盗刷就是非常必要的一件事,商家平台在上线前都需要 ...

  4. 阿里云 短信服务——开启验证码防盗刷监控

    阿里云 短信服务--短信发送频率限制 前言 系列博客 开启验证码防盗刷监控 操作步骤 添加联系人 补充(发送总量阈值和套餐包预警值) 如果博主的文章对您有所帮助,可以评论.点赞.收藏,支持一下博主!! ...

  5. 短信防火墙使用教程(短信防轰炸、防盗刷)

    短信服务接口安全是在开发或对接短信接口时尤为关注的问题.部分黑客可能出于恶意竞争或短信轰炸他人的目的,攻击短信服务接口,盗刷验证短信,造成资金损失.那么应该如何避免短信接口被恶意调用?本文为大家介绍短 ...

  6. java实现发送短信验证码、短信验证码防刷校验-49

    一:认证服务环境搭建 1.新建gulimail-auth-server 2.整合相关依赖 <!--引入commom依赖--><dependency><groupId> ...

  7. 解决网站漏洞 短信验证码被盗刷 该怎么办

    公司的商城网站刚上线运营不到一个星期,网站就被攻击了,导致公司网站的短信通道被人恶意刷了几万条短信,损失较大,同时服务器也遭受到了前所未有的攻击.CPU监控看到网站在被盗刷短信验证码的时候,CPU一直 ...

  8. 小豆社保「社保代缴」短信接口被盗刷解决方案-企业短信防火墙

    1 小豆社保业务及需求 半夜短信费用完, 怎么知道是否有问题? 小豆社保:是一家一站式人力资源SAAS服务云智慧平台,隶属于北京新琪科技有限公司, 说简单点就是解决工作变动无挂靠单位的人代缴社保的业务 ...

  9. 短信验证码被盗刷了怎么办?

    短信接口被恶意攻击的最常见的一种情况就是短信验证码被盗刷. 一般分两种情况: 攻击一个手机号 一般是针对个人的,当攻击者通过某种途径获取被攻击者的号码后就会利用某网站或者某一个软件的短信功能对其进行短 ...

  10. 我们公司的短信接口被刷了,瞬间损失两万,怎么解决?(短信接口被盗刷系列1)

    1 我们公司的短信接口被刷了,瞬间损失两万 前两天的中午像往常一样热,太阳不知疲倦的在天空燃烧,热跑了云彩和鸟儿,马上就要点燃空气和我的脑神经.为我和电脑降温的,是我简陋的书桌上的小电扇,没有它的话, ...

最新文章

  1. 此上下文中不允许函数定义。_深度好文 | 你知道Go中的 context 是怎么实现的吗?...
  2. C言语实现midpoint euler中点欧拉法解常微分方程(附完整源码)
  3. 人工智能——命题逻辑与谓词逻辑
  4. 狼奔权限管理系统[开源]
  5. ionic中定义路由的问题
  6. 满满的一整篇,全是 JVM 核心知识点!
  7. Windows电脑安装Linux系统的方法-Ubuntu版
  8. matlab系统稳定性仿真实验,基于Matlab的电力系统暂态稳定仿真实验与分析
  9. 传智php网课,传智自动刷网课视频工具
  10. 我国共计34个省级行政区,包括23个省、5个自治区、4个直辖市、2个特别行政区。
  11. excessive cpu 优化杀进程解决方案 android P
  12. pikachu漏洞练习平台XSS
  13. 【ResNet残差网络解析】
  14. 开课吧-智能物联网训练营Day2-QT布局和植物与僵尸类构造
  15. postgresql中patroni集群备库手动还原后,hac启动日志比主库多1
  16. python二级真题 d[i] = d.get(i,0)+1
  17. 史上最通俗易懂的ASM教程
  18. 题解: [GXOI/GZOI2019]与或和
  19. MiniOA最新下载
  20. 一劳永逸解决vs编译器无法使用scanf函数

热门文章

  1. 行业边缘丨中国电科发布“海雀”处理器;中科海微获千万融资;联想发布边缘服务器;风河加入CNCF云原生计算基金会成为银牌会员;...
  2. Linux中断(interrupt)子系统之三:中断流控处理层(转)
  3. 工程经济—技术方案不确定性分析
  4. / ./ ../相对路径详细解释
  5. C# Resharper的简单使用介绍
  6. huggingface datasets load_metric connecterror cannot reach
  7. Leetcode 1436. Destination City [Python]
  8. 如何安装python_如何安装Python?(第一节)
  9. 目标管理之SMART法则
  10. 服务器打不开jpg的文件,JPEG或JPG图片文件文件受损打不开,4种方法教你快速恢复!...