反调试原理
- 自定义webpack插件,给所有js添加
setInterval(() => {debugger}, 1000 * X)
, - setInterval循环执行,当用户打开浏览器控制台,每间隔X秒会跳到断点处,从而阻止用户调试
- 使用插件打包输入效果图
- 反调试效果图,如下图每2秒进一次断点
插件完整代码
/**
* 自定义webpack插件,当用户打开浏览器控制台,会自动跳转到断点初,用于防止非法人员调试前端代码
* 给所有js代码添加 setInterval(() => {debugger}, seconds)
*/
const { ConcatSource } = require('webpack-sources')
class JsAddDebuggerWebpackPlugin {
/**
* @param options.min 最小间隔秒数
* @param options.max 最大间隔秒数
*/
constructor (options = { min: 2, max: 20 }) {
this.min = options.min && options.min > 0 ? options.min : 1
this.max = options.max && options.max <= 600 ? options.max : 600
}
apply (compiler) {
compiler.hooks.afterCompile.tapAsync({
name: 'JsAddDebuggerWebpackPlugin',
}, (compilation, callback) => {
let assetNames = Object.keys(compilation.assets)
for (const name of assetNames) {
if (name.endsWith('.js')) { // 跳过非js文件
let seconds = Math.ceil(Math.random() * (this.max - this.min)) +
this.min
let appendContent = `setInterval(() => {debugger}, ${seconds} * 1000)`
compilation.updateAsset(
name,
old => new ConcatSource(old, '\n', appendContent),
)
}
}
callback()
})
}
}
module.exports = JsAddDebuggerWebpackPlugin
使用插件——以vue项目为例
- 在
vue.config.js
中引入插件
const JsAddDebuggerWebpackPlugin = require('./plugins/js-add-debugger-webpack-plugin')
- 调用插件
module.exports = {
configureWebpack: {
plugins:
process.env.NODE_ENV !== 'production'
? []
: [new JsAddDebuggerWebpackPlugin()],
},
}
- 引用插件效果图
问题
- 当setInterval间隔时间比较短,如1秒,浏览器同时加载的js文件比较多,如20个,对应用性能影响大吗?
- 此种反调试方式有无比较方便的破解方法?
1.禁用浏览器断点功能不算,那样用户自己也无法调试,也符合我们的目标
2.把所有js文件添加条件断点,return掉断点,这个也不算,js文件比较多,同一个js我也可以添加多个setInterval - 综上,此插件是可以用到生产环境?