【技术推荐】前端JS攻防对抗
字数 1109 2025-08-27 12:33:23

前端JS攻防对抗技术详解

1. 爬虫与反爬虫发展概述

1.1 攻防发展阶段对比

阶段 攻击手段 防御手段
1 简单脚本编写爬虫(Python、Java等) 检测User-Agent、HTTP Headers区分机器人
2 添加正常浏览器请求头部伪装用户 检测IP访问频率,封禁异常IP
3 使用IP代理池、秒拨等技术 网站重构,使用Ajax动态传输数据
4 分析数据传输接口直接获取数据 添加验证码、JS参数加密
5 深度学习破解验证码、JS调试破解参数加密 寻求第三方安全产品

1.2 现代反爬虫体系

  • 访问令牌(身份认证)
  • 验证码(滑动、逻辑、三维等)
  • 行为&指纹检测(人机区分)
  • 请求&响应加密

2. JS防破解技术

2.1 代码混淆技术

2.1.1 布局混淆

无效代码删除

  • 删除注释文本
  • 删除调试信息
  • 删除无用函数和数据
  • 删除缩进和换行符

标识符重命名

  • 单字母或简单组合
var animal = 'shark'  var a = 'shark'
  • 十六进制命名
var animal = 'shark'  var _0x616e696d616c = 'shark'
  • 作用域内标识符碰撞
function _$QQO(){
    var _$QQO,
}

垃圾代码添加

  • 插入大量无意义代码混淆视听

2.1.2 数据混淆

数字混淆

233  0351(八进制)  0xe9(十六进制)  0b11101001(二进制)

字符串混淆

  • 十六进制
'shark'  '\x73\x68\x61\x72\x6b'
  • Unicode编码
'shark'  '\u0073\u0068\u0061\u0072\u006b'
  • 转字节数组
function stringToByte(str){
    var bytearr = [];
    for(var i = 0; i < str.length; i++){
        bytearr.push(str.charCodeAt(i));
    }
    return bytearr
}
stringToByte('shark')  [115, 104, 97, 114, 107]
  • Base64编码
'shark'  'c2hhcms='

数组混淆

  • 元素引用和顺序打乱
var arr = ['log', 'Date', 'getTime']
console[arr[0]](new window[arr[1]]()[arr[2]]())

// 打乱数组元素
(function(arr, num){
    var shuffer = function(nums){
        while(--nums){
            arr.unshift(arr.pop());
        }
    };
    shuffer(++num);
}(arr, 0x10))

布尔值混淆

!undefined  true
!null  true
!0  true
!NaN  true
!""  true
!{}  true
  true

2.1.3 控制混淆

控制流平坦化
原始流程:

function source(){
    var a = 1;
    var b = a + 10;
    var c = b + 20;
    var d = c + 30;
    var e = d + 40;
    return e;
}

平坦化后:

function controlflow(){
    var controlflow_seq = '5|3|4|2|1|6'.split('|'), i = 0
    while(!![]){
        switch(controlflow_seq[i++]){
            case '1': var e = d + 40; continue;
            case '2': var d = c + 30; continue;
            case '3': var b = a + 10; continue;
            case '4': var c = b + 20; continue;
            case '5': var a = 1; continue;
            case '6': return e; continue;
        }
        break;
    }
}

逗号表达式

function source(){
    var a, b, c, d, e;
    return a = 1, b = a + 10, c = b + 20, d = c + 30, e = d + 40, e
}

// 或
function source(){
    var a, b, c, d, e;
    return e = (d = (c = (b = (a = 1, a + 10), b + 20), c + 30), d + 40);
}

2.2 混淆工具

在线混淆工具

AST(抽象语法树)处理

  • 使用Babel等工具进行语法树转换
  • AST处理控制流平坦化示例:
// 还原思路:
// 1. 获取分发器生成的顺序
// 2. 把分支语句和条件对应生成case对象
// 3. 利用分发器顺序从case对象获取case
// 4. 输出还原后的代码

const visitor = {
    WhileStatement(path){
        let {body} = path.node;
        let switch_statement = body.body[0];
        // ... 详细处理逻辑
        path.replaceWithMultiple(tmp_array);
        path.scope.crawl();
    }
}
traverse(ast, visitor);

3. 反调试技术

3.1 控制台防护

阻止控制台打开

window.addEventListener('keydown', function(event){
    if(event.key == "F12" || ((event.ctrlKey || event.altKey) && 
       (event.code == "KeyI" || event.key == "KeyJ" || event.key == "KeyU"))){
        event.preventDefault();
        return false;
    }
});
window.addEventListener('contextmenu', function(event){
    event.preventDefault();
    return false;
});

窗口尺寸检测

(function(){
    'use strict';
    const threshold = 160;
    setInterval(() => {
        const widthThreshold = window.outerWidth - window.innerWidth > threshold;
        const heightThreshold = window.outerHeight - window.innerHeight > threshold;
        if(widthThreshold || heightThreshold){
            emitEvent(true, orientation);
        }
    }, 500);
})();

3.2 调试器防护

定时debugger

function debug(){
    debugger;
    setTimeout(debug, 1);
}
debug();

时间差检测

addEventListener("load", () => {
    var threshold = 500;
    const measure = () => {
        const start = performance.now();
        debugger;
        const time = performance.now() - start;
        if(time > threshold){
            document.write("<p>DevTools were open since page load</p>");
        }
    }
    setInterval(measure, 300);
});

3.3 控制台输出防护

清空控制台

function clear(){
    console.clear();
    setTimeout(clear, 10);
}
clear();

3.4 断点调试防护

时间检测断点

var timeSinceLast;
addEventListener("load", () => {
    var threshold = 1000;
    const measure = () => {
        if(!timeSinceLast){
            timeSinceLast = performance.now();
        }
        const diff = performance.now() - timeSinceLast;
        if(diff > threshold){
            document.write("<p>A breakpoint was hit</p>");
        }
        timeSinceLast = performance.now();
    }
    setInterval(measure, 300);
});

scope检测

function malicious(){
    const detect = (function(){
        const dummy = /./;
        dummy.toString = () => {
            alert('someone is debugging the malicious function!');
            return 'SOME_NAME';
        };
        return dummy;
    }());
}

3.5 事件调用防护

堆栈检测

function test(){
    console.log(new Error().stack);
    // 或
    try{throw new Error('');}catch(error){stack = error.stack || '';}
    console.log(stack);
}

3.6 函数属性防护

函数防劫持

function hijacked(fun){
    return "prototype" in fun || 
           fun.toString().replace(/\n|\s/g,"") != "function"+fun.name+"(){[nativecode]}";
}

// 设置不可修改
Object.defineProperty(window, 'eval', {
    writable: false,
    configurable: false,
    enumerable: true
});

3.7 NodeJS调试防护

代码格式化检测

function y(){
    var t = (function(){
        var B =!![];
        return function(W, i){
            var F = B ? function(){
                if(i){
                    var g = i['apply'](W, arguments);
                    i = null;
                    return g;
                }} : function(){};
            B =);
    var l = t(this, function(){
        return l['toString']()['search']('( )['toString']()['constructor'](l)['search']('( );
    });
    l();
    console['log']('aaaa');
    console['log']('ccc');
};
y();

4. 高级防护手段

  1. 自定义编译器
  2. WebAssembly技术
  3. 浏览器特性挖掘
  4. 结合业务场景的定制化混淆方案

5. 总结

前端JS防破解需要结合代码混淆和反调试技术,根据业务特点选择合适的防护策略:

  1. 代码混淆:从布局、数据、控制三个层面进行混淆,增加代码阅读难度
  2. 反调试:防止动态调试分析,保护关键逻辑不被轻易发现
  3. 组合使用:多种技术组合使用,形成防御体系
  4. 性能平衡:在安全性和性能之间找到平衡点

通过合理运用这些技术,可以有效提高前端代码的安全性,防止恶意分析和爬虫攻击。

前端JS攻防对抗技术详解 1. 爬虫与反爬虫发展概述 1.1 攻防发展阶段对比 | 阶段 | 攻击手段 | 防御手段 | |------|----------|----------| | 1 | 简单脚本编写爬虫(Python、Java等) | 检测User-Agent、HTTP Headers区分机器人 | | 2 | 添加正常浏览器请求头部伪装用户 | 检测IP访问频率,封禁异常IP | | 3 | 使用IP代理池、秒拨等技术 | 网站重构,使用Ajax动态传输数据 | | 4 | 分析数据传输接口直接获取数据 | 添加验证码、JS参数加密 | | 5 | 深度学习破解验证码、JS调试破解参数加密 | 寻求第三方安全产品 | 1.2 现代反爬虫体系 访问令牌(身份认证) 验证码(滑动、逻辑、三维等) 行为&指纹检测(人机区分) 请求&响应加密 2. JS防破解技术 2.1 代码混淆技术 2.1.1 布局混淆 无效代码删除 删除注释文本 删除调试信息 删除无用函数和数据 删除缩进和换行符 标识符重命名 单字母或简单组合 十六进制命名 作用域内标识符碰撞 垃圾代码添加 插入大量无意义代码混淆视听 2.1.2 数据混淆 数字混淆 字符串混淆 十六进制 Unicode编码 转字节数组 Base64编码 数组混淆 元素引用和顺序打乱 布尔值混淆 2.1.3 控制混淆 控制流平坦化 原始流程: 平坦化后: 逗号表达式 2.2 混淆工具 在线混淆工具 obfuscator.io AST(抽象语法树)处理 使用Babel等工具进行语法树转换 AST处理控制流平坦化示例: 3. 反调试技术 3.1 控制台防护 阻止控制台打开 窗口尺寸检测 3.2 调试器防护 定时debugger 时间差检测 3.3 控制台输出防护 清空控制台 3.4 断点调试防护 时间检测断点 scope检测 3.5 事件调用防护 堆栈检测 3.6 函数属性防护 函数防劫持 3.7 NodeJS调试防护 代码格式化检测 4. 高级防护手段 自定义编译器 WebAssembly技术 浏览器特性挖掘 结合业务场景的定制化混淆方案 5. 总结 前端JS防破解需要结合代码混淆和反调试技术,根据业务特点选择合适的防护策略: 代码混淆 :从布局、数据、控制三个层面进行混淆,增加代码阅读难度 反调试 :防止动态调试分析,保护关键逻辑不被轻易发现 组合使用 :多种技术组合使用,形成防御体系 性能平衡 :在安全性和性能之间找到平衡点 通过合理运用这些技术,可以有效提高前端代码的安全性,防止恶意分析和爬虫攻击。