一 事件简述

这是一件发生在前段时间的事情,当时的情况是这样的:一个新的功能模块上线之后,出现短信接口被恶意访问调用的情况,请求数量很大,而且通过查看短信服务商控制台也发现,短信发送量在飙升,看着统计曲线的增长,紧张的气氛也渐渐变得更浓,很明显,事情并不是遇到一个bug那么简单,因为牵涉到服务费用,需要立即解决。

当然,接口被恶意访问的这个问题已经解决,因此写了这篇文章,可以做一下简单的记录,并且静下心来分析一下其中的问题了,看完这个案例,大家也可以一起讨论讨论。

二 问题分析

这是当时的短信接口日志数量曲线,某一个时间点突然增长了起来并且没有降下去的意思,通过日志分析发现,***者用的不同IP、不同号码进行恶意调用,请求量较大,赶紧将事件做了记录并通知了相关人员,和同事做了沟通后,大家也都提出了自己的意见:有人说赶紧修改前端功能,发一版新的APP,有人说修改后端代码,紧急补救一下,也有人说要不要先关停一下服务......在网上技术论坛搜了一下相关问题,好像碰到这种事情的也不少,基本思路都是加验证码,做好安全验证,被***了无可奈何之类的云云。

简单对各个方案做了整理:

修改url(APP已经上线,暂时无法修改)。

添加验证码验证(APP已经上线,暂时无法通过这种方式来解决)。

停掉短信服务(不现实,其他功能模块也需要调用短信服务,不考虑实施)。

短信服务商自带防***,等一段时间,让***者自己停止***(虽然短信服务商自带防***,但是依然会出现大量的垃圾请求,而且服务商只是针对次数和时间做了限制,一段时间后依然会发送短信,因此,危害和损失还是不小的,问题依然急需处理掉,装鸵鸟是解决不了问题的)

三 应急解决方案

在用户交互界面拦截请求已经不现实了,因为移动端短时间内是无法立刻升级的,而等待***停止的方案也不可取,选择逃避和等待是解决不了问题的,因此最终的决定就是修改后端接口逻辑和代码。找到最关键的问题,虽然存在网络***,但是真正需要立刻解决的是短信服务接口的调用问题,当务之急是修改短信发送接口,尽快止损。

通过讨论和简单的分析,最终是决定先修改后端逻辑紧急打一个线上补丁,移动端也做同步修改,等待发版。

1 黑名单模式拦截

由于接口一直被调用,需要紧急处理,减少短信服务费用的损失,因此一开始的出发点放在了手机号码上,针对手机号码做验证,采用黑名单的模式,对于此接口中出现的号码,在一定次数的请求后就立刻加入到黑名单列表中,再次请求时,如果是黑名单中的号码,直接返回错误码,不做任何其他处理,也不会调用短信发送接口,这种方式可能会误伤到真实用户,但是情况比较特殊,因此就选择了这个应急方案,紧急修改了后端代码,对部分代码逻辑做了修改,添加手机号码的黑名单功能。在短信发送模块中,对号码进行验证,如果一段时间内多次请求同一个号码的话,将号码存入数据库视为黑名单中的号码,不会发送短信。

拦截了近700个手机号码,这些号码中应该很多是空号吧:

2 请求验证拦截

上面的方法虽然起到了一定的作用,但是依然无法很好的解决掉问题,为什么这么说呢?因为即使利用了黑名单模式,在进入到黑名单列表之前,依然会发送短信,试想一下每分钟1000次的恶意请求,即使拉黑了其中的一部分号码,还是会有一部分漏网之鱼会被当做正常数据,然后请求短信服务商接口发送短信,这也是一个不小的体量,黑名单模式可以处理一些问题,但是只能起到微小的作用,还需要进一步修改后端逻辑。

回到大家都提到的用验证码做安全验证,前端虽然无法立即更新添加验证码界面和处理逻辑,但是验证码的设计就是识别正常请求和非法请求,因此找到一个方法能够识别请求是否非法即可,并不一定非要添加验证码功能。本模块在设计接口之初,就做了数据传输规定,移动端向后端发送请求时,必须在请求头中放入一些参数,这些参数本来是做分析用的,但是在这里起到了很大的作用,因此可以在请求对象request上做文章,***请求只是发送请求到url,***者也只知道url并不知道请求参数设计,因此针对这点做验证,应该可以拦截掉所有的恶意请求了,甚至请求都不会到达黑名单验证环节就已经被处理掉了。

再次修改后端代码,由请求信息request对象入手,从请求对象request中提取数据做校检,甄别是否为正常请求,如果是正常请求,数据中的参数不会为空且参数值是可控的,而恶意虚假请求中则不含有这些参数,因此直接返回错误码不作处理即可,这个补丁打上之后,短信服务费用的损失就不会再增加了。

3 应急方案总结

不管是前端验证码,或者这次采取的验证请求方式,都是一种验证方式,用来甄别是否为移动端APP发送过来的正常请求,如果不是,就不做处理,通过日志和黑名单数据可以得出结论,短信发送的问题已经解决。

这个事件也说明,安全验证不能掉以轻心,也不能心存侥幸心理,一旦被心存恶意之人找到漏洞,还是挺难过的。前端验证没有完全考虑到,后端验证拦截也做的不到位,因此出现了这种情况,需要检讨和反思,而且处理方式也不是特别得当,一开始的黑名单模式并没有完全杜绝掉短信发送的问题,又去做了后面的补救,当时确实比较紧张,因此想到能用的方法就赶紧用在了修改上面。

为何说惊险和紧张,试想一下:周末刚刚在家里修整了两天,周一的早晨,打完卡坐在工位上悠闲的喝着茶,悠悠的打开浏览器查看系统日志,忽然发现这个访问量有点大呀,隐隐觉着不对,认真的查了一下发现,接口被***了,而且是短信发送的接口,看着一条条的短信因为***而发送出去,那一条条的短信,是白花花的银子啊,能不紧张吗!什么感觉?吃着火锅唱着歌,突然就被麻匪给劫了,跟葛大爷一样,就是那种感觉。

至于说险胜,是因为虽然暂时解决了短信发送的问题,不会再进一步的造成金钱的损失,却存在另外一个问题:大量的恶意请求。

四 最终解决方案

使用短信防火墙。 从以下几个方面概括一下:

新昕科技在交易反欺诈核心上, 通过AI快速学习机制,结合国际领先的设备指纹技术,首次推出无需图形验证码机制的企业短信防火墙,三步完成下载对接。

第一步:获取防火墙帐号密钥

进入 防火墙控制台,在左侧导航栏选择【网站管理】,进入网站管理页面,单击【发到邮箱】接收密钥。

第二步:下载防火墙服务器

前往新昕科技官网,在顶部导航栏选择【解决方案】>【下载中心】,进入下载中心页面,找到短信防火墙服务器安装包,点击【下载链接】即可下载。

第三步:前后端接入

前端接入

Java 在页面合适的位置(标签内)加入以下代码引入JS文件:

PHP 在页面合适的位置(标签内)加入以下代码引入JS文件:

后端接入

Java

修改配置(和业务系统同系统不需要修改):

newxtc.ini (存放位置:"/WEB-INF/classes/newxtc.ini")

修改参数(fireWareUrl)--> fireWareUrl=http://localhost:7502

短信下发

public RetMsg smsSend(HttpServletRequest request, HttpServletResponse response, String clientMobile) {

RetMsg retMsg = new RetMsg(-1, "系统异常");

FwClient fwClient = new FwClientImpl();

try {

// 1 调用【短信防火墙】短信发送请求

HashMap < String, Object > paramMap = fwClient.getSendReq(request, clientMobile);

String jsonReq = fwClient.execReq(paramMap);

String smsSendRet = fwClient.getRetVaule(jsonReq, "riskResult");

if("REJECT".equals(smsSendRet)) {

retMsg.setRet(3);

retMsg.setMsg("请求过于频繁");

}

else {

// 业务 TODO

// 业务调用短信接口 TODO

// 调用短信接口 结束

if(smsRetMsg != null && smsRetMsg.getRet() == 0) {

// 2 调用【短信防火墙】成功结果

fwClient.execSucc(paramMap);

logger.debug("send succ");

retMsg.setRet(0);

retMsg.setMsg("发送验证码成功");

}

else {

// 2 调用【短信防火墙】失败结果

SmsVerifyCache.getInstance().remove(clientMobile);

fwClient.execFail(paramMap);

retMsg.setRet(-1);

retMsg.setMsg("发送验证码失败");

}

}

}

catch(Exception e) {

for(StackTraceElement elment: e.getStackTrace()) {

logger.error(elment.toString());

}

}

return retMsg;

}

短信验证

public RetMsg smsVerify(HttpServletRequest request, HttpServletResponse response, String clientMobile, String smsVerifyCode) {

FwClient fwClient = new FwClientImpl();

RetMsg retMsg = new RetMsg(-1, "系统异常");

if(smsVerifyCode == null || smsVerifyCode.isEmpty()) {

retMsg.setRet(1);

retMsg.setMsg("输入验证码为空");

}

else {

// 1 调用【短信防火墙】验证请求

HashMap < String, Object > paramMap = fwClient.getVerifyReq(request, clientMobile); // 请求防火墙

String jsonReq = fwClient.execReq(paramMap);

// 报文处理

String smsSendRet = fwClient.getRetVaule(jsonReq, "riskResult");

if("REJECT".equals(smsSendRet)) {

retMsg.setRet(3);

retMsg.setMsg("请求过于频繁");

}

// 业务 TODO

if(cacheSmsVerify != null && cacheSmsVerify.getVerifyCode() != null && !cacheSmsVerify.getVerifyCode().isEmpty()) {

if(cacheSmsVerify.getVerifyCode().equals(smsVerifyCode)) {

retMsg.setRet(0);

retMsg.setMsg("验证成功");

}

else {

retMsg.setRet(1);

retMsg.setMsg("验证码错误");

}

}

else {

retMsg.setRet(-9);

retMsg.setMsg("验证码超时");

}

if(retMsg.getRet() == 0) {

// 2 调用【短信防火墙】成功结果

fwClient.execSucc(paramMap);

}

else {

// 2 调用【短信防火墙】失败结果

fwClient.execFail(paramMap);

}

}

return retMsg;

}

查看防火墙数据

通过风控数据看板,可查看1-30天的验证情况、风控拦截情况以及验证事件触发的风控策略情况。

进入防火墙控制台,在左侧导航栏选择【风险大盘】,进入风险大盘页面。

java黑名单校验_短信验证码被刷怎么办?java 短信验证码防刷策略相关推荐

  1. 产品防护:5种常见的短信验证码防刷策略

    短信验证码作为重要的身份验证工具,因其操作简便.安全性高.时效性强等优点已被开发人员广泛使用.但因其获取便利.限制较少容易被不法分子利用进行短信轰炸,恶意刷掉大量短信费用,给公司或个人造成大量的金钱损 ...

  2. java调用短信验证失败_短信验证码被刷怎么办?java 短信验证码防刷策略

    一 事件简述 这是一件发生在前段时间的事情,当时的情况是这样的:一个新的功能模块上线之后,出现短信接口被恶意访问调用的情况,请求数量很大,而且通过查看短信服务商控制台也发现,短信发送量在飙升,看着统计 ...

  3. java俄罗斯方块视频_[VIP视频]【A0233】java面对对象编程-俄罗斯方块视频教程 高清视频 百度云 百度网...

    Java视频教程名称:java面对对象编程-俄罗斯方块视频教程  俄罗斯方块视频教程 $ X0 X1 Z: W4 P3 T  e. m3 q百度网盘下载链接: . M% x- I- V5 p( J 游 ...

  4. java 底层运行_从表面到底层丨Java和JVM的运行原理,现在带给你

    Java,编程语言,被创造于90年代初,在经历了这么多年的风风雨雨,Java已经成长为世界第一的编程语言,根据往期以及目前的数据来看,Java的使用频率为全球第一,即使偶尔会有第二第三的情况,但是这依 ...

  5. java xslt 数据转换_如何将xslt结果转换为Java对象?

    我有一个 XML文件: Empire Burlesque Bob Dylan USA Columbia 10.90 1985 而这个XSL文件: 现在我想将结果转换为Java类. Java的: @Xm ...

  6. eclipse java工程目录_转载:Eclipse下的java工程目录

    对新手来讲,一个Java工程内部的多个文件夹经常会让大家困惑.更可恶的是莫名其妙的路径问题,在Eclipse编写Java程序中,出现频率最高的错误很可能就是路径问题. 这些问题原因其实都是一个,就是关 ...

  7. ubuntu java classpath 设置_在Ubuntu中正确设置java classpath和java_home

    我有错误 Exception in thread"main" java.lang.NoClassDefFoundError: 当我尝试在Ubuntu上运行编译类时.我使用的是一个非 ...

  8. java string范围_字符串索引超出范围? (Java,子字符串循环...

    我正在为COSC课程制作的该程序编译不正确,但我不断收到错误消息: 线程"主"中的异常java.lang.StringIndexOutOfBoundsException:字符串索引 ...

  9. java自学难点_分享在达内教育培训Java的感受

    刚在达内教育培训完java,给即将来培训以及已经在培的学员分享下我的感受 回想一下在达内教育学习Java时的情景,我仍然兴奋不已,其实在刚接触Java时,自己确实有点晕,但经过一段时间学习,逐渐走出了 ...

最新文章

  1. linux 6.8 dns,CentOS6.8下安装DNS服务器
  2. hadoop 实战练习_hadoop入门到实战(2)hive经典练习题
  3. Unity3D研究院之Editor下监听Transform变化
  4. 开发工具使用技巧和插件大总结
  5. Spring Mvc中使用Task实现定时任务,以及遇到的一个问题
  6. Comparable和Comparator的区别
  7. Android在全球的市场份额跃居全球第一
  8. HDU - 4497 GCD and LCM 数论gcd
  9. Kotlin静态方法定义和调用
  10. jqgrid表格下拉搜索多选框优化—使用select下拉多选插件
  11. 搭载麒麟990 5G SoC 华为MatePad Pro 5G全球首发
  12. HadoopLearning
  13. echarts 中国地图,tooltip,legend同时显示多组数据
  14. 不改动当前账户密码的情况下,启用其他账户登录windows系统
  15. 详细解说Java 技术的新纪元
  16. whatsns与tipask_tipask重大安安全漏洞之最佳答案bug修复
  17. 创新实践部第一次培训---算法入门
  18. 23年教资面试开始啦个人报名流程
  19. (转)正则表达式中的点星问号 .*? 或点星加号 .*+ 是什么意思
  20. 一文带你了解学习python的用处及好处,建议收藏

热门文章

  1. PyTorch疑难杂症(1)——torch.matmul()函数用法总结
  2. windows用户名为中文,改为英文,解决开发者安装软件频繁报错问题
  3. 常用的视频的格式,分辨率,帧速率
  4. Mac M1芯片Java开发环境搭建 · JDK安装
  5. .Net Core使用google authenticator打造用户登录动态口令
  6. ios支付宝api开发个人商城支付功能文档
  7. 古诗词模板html,诗词鉴赏万能模板
  8. MySQL开发技巧——查询、索引和完整性
  9. 材料科学计算机科学,计算机在材料科学中的应用---完整版.doc
  10. 红米mote使用java,华为P30 Pro vs 红米Note8 Pro: 用数据对决相机