SpringBoot 开发之防止微信用户恶意访问微信公众号

本文介绍了一次公众号接口遭受攻击的经历,并详细记录了攻击手法及其应对措施,包括无token访问拦截、固定及动态IP限流策略、登录接口验证码保护等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:前段时间可能是碰到同行了,公司上线的公众号接口被人疯狂的访问,导致服务器CPU资源被严重消耗,系统也在接近崩溃的边缘,虽然后面紧急处理抢救回来,但是我觉得这个事情还是应该重视一下,记录下来。
在这里插入图片描述

一、经过这次事件,我把攻击手法进行分类

  1. 无token或者无效token访问
  2. 固定IP携带有效token访问
  3. 动态IP携带有效token访问

1.1 无token或者无效token访问防护

正常进入服务器的访问请求都会先经过拦截器,对不携带token和携带无效token的访问进行拦截(由于是公众号接口,这边放开了对空token的限制,没想到却被居心不良的人给钻了空子 o(╥﹏╥)o,一定要吸取教训,防人之心不可无!!!)

1.2 固定IP携带有效token访问防护

当用户使用有效的token进行访问,普通的拦截器是拦不住的,因为他就相当于正常的用户正常访问,这个就需要在原有拦截器的基础上新增一个IP地址限流,限制的规则有很多。

我采取的是:限制每秒内同一IP地址对同一接口的次数,也就是同一IP对同一接口每秒访问不得超过多少次,否则加入黑名单(加入黑名单多久可以自行处理)

1.3 动态IP携带有效token访问防护

原本我也以为,把IP地址防住就OK了,没想到我还是太天真 °(°ˊДˋ°) °,打开日志一看,全是虚拟IP,上网上一查,发现IP修改器实在太多了
在这里插入图片描述
苦逼的生活从无尽的填坑开始,既然IP地址防不住,那我就从你token里面携带的微信用户信息下手 (ง •̀_•́)ง,将之前IP黑名单拦截器升级为微信用户访问拦截器。

实现原理一样,只是把之前的IP地址改成微信用户的 openId:也就是同一 openId对同一接口每秒访问不得超过多少次,否则加入黑名单。

1.4 附加:动态IP访问登录接口(访问登录接口是不需要携带token的)

前三种都是在公众号上发现的,这我在网上查询的时候无意间浏览到的,也在这边记录一下,面对这种情况,之前所说的拦截器怕是也没有用武之地。

对于这种情况我能想到的只有在登录接口加上验证码,先判断验证码是否正确再去做用户判断。

这样做一来可以防止他人使用程序对用户名密码进行破解,二来可以避免不良分子向系统注水。

附:黑名单拦截器实现

token 拦截器的实现和 登录验证码的实现网上已经有很多了,我这边附上黑名单过滤器的实现仅供参考。

在访问进入请求方法的时候增加黑名单判断器,返回 true 拦截,返回 false 放行

/**
     * 黑名单判断器(为了方便我这边保存到缓存中,最好是保存到 Redis)
     * @param apiCode 接口编号
     * @param uCode 用户编号(可以是ip 也可以是 openId)
     * @return true 黑名单,false 正常
     */
     public static boolean weChatBlacklist(String apiCode, String uCode) {
        // 黑名单用户不予许访问
        Object object = CacheMgr.getValue("wechatBlacklist-" + uCode);
        if(object != null){
            return true;
        }
        // 查询缓存中当前IP访问当前接口的次数
        Integer count = (Integer) CacheMgr.getValue(apiCode+"-" + uCode);
        if(count == null){
            // 如何缓存为空,保存访问次数
            CacheMgr.addCache(apiCode+"-" + uCode,1);
            // 开启新的线程,定制一秒后计划
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 暂停1秒
                        Thread.sleep(1000);
                        // 1秒后查询访问总数
                        Integer visits = (Integer) CacheMgr.getValue(apiCode+"-" + uCode);
                        if(visits!=null){
                            log.info(apiCode+"-" + uCode+":"+cumulative);
                            // 如果1秒后缓存访问次数不为空,删除缓存
                            CacheMgr.removeCache(apiCode+"-" + uCode);
                            // 一秒后缓存中访问次数超过x则加入黑名单(x值视接口具体情况而定)
                            if(visits>maxVisits){
                                // 用户每秒访问数超过 maxVisit,加入黑名单
                                CacheMgr.addCache("wechatBlacklist-" + uCode,uCode);
                                // 此处再将 uCode 持久化到数据库中,程序再次启动时读取
                            }
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            });
            thread.start();
        } else {
            CacheMgr.addCache(apiCode+"-" + uCode,++count);
        }
        return false;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值