抓内贼的N种方法——如何防止利用F12开发者工具的攻击

家贼难防

现场反馈一些业务上不可以取消的订单被莫名奇妙的取消了。
代码本身没有任何问题,要知道我们对界面上对于订单是否可以cancel的控制如下:

// 调用服务查询订单是否可以cancel
Action.checkCanCancelOrder({
    
    orderNbr:orderNbr}, function(canCancel) {
    
    
  // 可以cancel,则cancel按钮设置disabled为false,可以点击
  if (canCancel) {
    
    
      this.$(".js-cancel-order").attr("disabled", false);
  }
  // 否则设置disabled为true,不可点击
  else {
    
    
    this.$(".js-cancel-order").attr("disabled", false);
  }
})

客户调查跟踪发现是:
客户的营业员自己通过浏览器开发者工具,修改页面按钮disabled,将不可操作的cancel按钮修改成了可操作的。
将cancel按钮对应的dom元素的disabled属性删除,这样cancel按钮就可以点击了,订单也就被取消了。
在这里插入图片描述

咱就是说,这家贼难防啊!!!
于是乎,客户就要求我们能够对cancel功能进行限制,限制住这种非法行为,并且需要记录非法操作人员的信息,以期望能够遏制惩罚这种行为。

防贼大法百家争鸣

如何避免这类操作呢?群里的大佬们给出了自己的解决方案

大佬A:抽象管理,基于服务,统一校验。。。

大佬A发言如下:

这是普通黑客的一般操作~
他今天试这个 明天就可以试别的~
总有一天,能找到一个能获利的接口。
等他找到那个接口,那就是安全一级故障了~[流汗]
不过放心 我们有方案~等会开完会一起当面讨论下

听到大佬发言,心里一阵狂喜,原来产品已经实现某种限制了吗,是否是能拿来即用?
最后在期待中,大佬来了,洋洋洒洒三千言,什么抽象管理,什么相对统一校验,什么基于服务,支持配置。。。
听得我晕晕乎乎,最后才听明白——只是一个设想,目前还没有做出来。。。嗯最关键的是,就算有,那根本的业务逻辑还是得定制自己处理。。。
暂时不能付诸行动,先放一放吧。。。

大佬B:禁用开发者工具

既然是从浏览器开发者工具去修改的,那就从这个源头解决。比如对F12加个监听,禁止打开开发者工具弹窗

这个网上有一些实践了,比如代码如下:

/*禁用f12建*/
window.onkeydown = window.onkeyup = window.onkeypress = function (event) {
    
    
    // 判断是否按下F12,F12键码为123
    if (event.keyCode === 123) {
    
    
        event.preventDefault(); // 阻止默认事件行为
        window.event.returnValue = false;
    }
}

或者其他一些实现方式。
虽然说也是一种解决办法,但是不能从根本上解决问题——开发者工具也可以通过其他方式打开——而且总不能因为这一个改动增加我们自己开发debug的障碍。

大佬C:双重校验

双重校验。即服务端cancel前再对订单进行一次能否cancel的校验。

点击cancel后 真正cancel前再进行一次能否cancel的校验。代码如下:

// 原逻辑
public int cancelOrder(request) {
    
    
    doCancel(request);
}
// 修改为
public int cancelOrder(request) {
    
    
    // 先校验是否可以cancel
    boolean cancelCancel = checkCancel(request);
    if (cancelCancel) {
    
    
        doCancel(request);
    }
    else {
    
    
        // 记录操作员信息
        doLog(request);
    }
}

大佬D:更加巧妙的双重校验

双重校验的确能快速的解决问题,但是增加了校验逻辑。目前来看我们查询能否cancel的逻辑比较复杂,这样可能有性能的影响。或许我们可以换种方法来进行双重校验。

当第一次校验能否cancel后,如果可以cancel,服务端可以返回给前台一把钥匙cancelKey,cancelKey是由订单某些信息加密而成,无法破解。当点击cancel后需要带着这把钥匙,提交给服务端,服务端根据订单信息重新计算加密的key来验证是否正确,如果正确则继续取消订单。否则就是非法操作,将信息记录下来。
代码如下:

  • 校验订单能否取消的服务 增加cancelKey的返回
public response checkCanCancel(request) {
    
    
    boolean canCancel = doCheck(request);
    if (canCancel) {
    
    
        response.setCancel(true);
        // 根据订单信息计算出一个cancelKey 加密
        String cancelKey = calCancelKey(request);
        response.setCancelKey(cancelKey);
    }
    return response;
}
  • 前台根据返回结果控制cancel按钮disabled,并记录cancelKey
// 调用服务查询订单是否可以cancel
Action.checkCanCancelOrder({
    
    orderNbr:orderNbr}, function(response) {
    
    
  // 可以cancel,则cancel按钮设置disabled为false,可以点击
  if (response.canCancel) {
    
    
      this.$(".js-cancel-order").attr("disabled", false);
      this.cancelKey = response.cancelKey;
  }
  // 否则设置disabled为true,不可点击
  else {
    
    
    this.$(".js-cancel-order").attr("disabled", false);
       this.cancelKey = null;
  }
})
  • 再次点击cancel时前台需要传参cancelKey
// 调用cancelOrder服务
Action.cancelOrder({
    
    orderNbr:orderNbr, cancelKey:this.cancelKey}, function(response) {
    
    
  //....
})
  • 后台cancelOrder服务校验cancelKey是否正确
public int cancelOrder(request) {
    
    
    // 计算cancelKey
    String newCancelKey = calCancelKey(request);
    // 判断cancelKey是否正确
    if (newCancelKey.equals(request.cncelKey)) {
    
    
        doCancel(request);
    }
    else {
    
    
        // 记录操作员信息
        doLog(request);
    }
}

打贼后记

最终我们为了快速解决问题,采用了大佬D的解决办法。
升级后一定程度上遏制了家贼的猖狂行为,并为惩处提供了一定的证据。
不知道大家有没有遇到了类似的奇葩问题?有没有大佬再指点一二,给出更合适的解决办法?
欢迎在评论区留言!!!

猜你喜欢

转载自blog.csdn.net/qq_34577234/article/details/125610821