1. 小程序安全测试全景概览
微信小程序作为轻量级应用形态,其安全测试涉及从静态代码到动态行为的完整链路。与原生App不同,小程序运行在微信沙箱环境中,但依然存在接口越权、数据泄露、逻辑漏洞等风险点。典型的测试路径包括:通过解包获取前端代码、分析网络通信协议、追踪运行时内存数据。其中反编译环节需要处理.wxapkg包文件,而动态调试则依赖Xposed框架或frida注入。
注意:所有测试行为必须获得授权,未经许可对第三方小程序进行逆向可能涉及法律风险
2. 小程序包体获取与反编译实战
2.1 包体提取技术路线
安卓设备上可通过ADB命令提取缓存包:
adb pull /data/data/com.tencent.mm/MicroMsg/{userhash}/appbrand/pkg/iOS则需要越狱设备访问/var/mobile/Containers/Data/Application/WeChat/Documents/{userhash}/WeApp/LocalCache/release/
获取到的.wxapkg文件需使用unveilr等工具解包:
import unveilr decrypted = unveilr.decrypt(open('__APP__.wxapkg', 'rb').read()) with open('decrypted.wxapkg', 'wb') as f: f.write(decrypted)2.2 反编译核心步骤
- 使用wxappUnpacker处理解密后的包体:
node wuWxapkg.js decrypted.wxapkg -o ./output- 解析后的项目包含:
- app-service.js(业务逻辑)
- page-frame.html(页面框架)
- 各页面wxss/json配置
常见问题处理:
- 遇到"unsupported version"提示时,需更新解包工具版本
- 部分小程序启用分包加载,需要合并多个子包分析
3. 动态调试技术体系
3.1 抓包方案对比
| 工具 | 适用场景 | 配置复杂度 | HTTPS解密 |
|---|---|---|---|
| Charles | 全流量记录 | 中等 | 需装证书 |
| Fiddler | Windows环境调试 | 低 | 需装证书 |
| Wireshark | 底层协议分析 | 高 | 不支持 |
| Burp Suite | 安全测试 | 高 | 需装证书 |
手机端配置要点:
- 设置代理服务器IP和端口(通常8888)
- 安装CA证书到系统信任区
- 关闭微信的"HTTP2.0开关"(在帮助与反馈长按菜单)
3.2 运行时调试技巧
安卓设备可通过Xposed框架加载模块:
public class WeChatHook implements IXposedHookLoadPackage { public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) { if (lpparam.packageName.equals("com.tencent.mm")) { XposedHelpers.findAndHookMethod( "com.tencent.mm.plugin.appbrand.j", lpparam.classLoader, "invokeHandler", String.class, String.class, JSONObject.class, new XC_MethodHook() { /* 处理逻辑 */ }); } } }内存dump关键命令:
frida -U -f com.tencent.mm -l dump.js其中dump.js包含搜索敏感字符串的正则模式。
4. 静态代码审计要点
4.1 架构风险识别
检查解包后的项目结构:
├── app.js # 全局逻辑 ├── app.json # 页面配置 ├── pages/ # 页面组件 │ ├── index/ │ │ ├── index.js # 业务逻辑 │ │ ├── index.wxml # 模板 │ │ └── index.wxss # 样式 └── utils/ └── request.js # 网络请求封装重点关注:
- 请求统一封装文件(如request.js)是否包含敏感头信息
- WXML中是否存在未过滤的
<web-view>标签 - 配置文件是否泄露API密钥
4.2 典型漏洞模式
- 硬编码密钥:
const API_SECRET = 'a1b2c3d4e5f6' // 反编译可见- 不安全的存储:
wx.setStorageSync('token', res.data) // 明文存储- 逻辑绕过:
if(userInfo.vip === false){ // 前端校验可被修改 }5. 网络通信深度分析
5.1 协议特征识别
微信小程序流量特征:
- Host头为二级域名.service.wechat.com
- User-Agent包含"MicroMessenger"标识
- 请求体常用JSON格式,可能采用自定义编码
关键接口定位方法:
- 搜索包含"https://"的字符串
- 追踪wx.request调用栈
- 分析域名解析行为
5.2 接口安全测试
使用Burp Suite测试流程:
- 重放请求修改参数(如userID)
- 测试越权访问(水平/垂直)
- 检查响应头安全策略:
- CORS配置不当
- 缺少X-Frame-Options
- 敏感信息泄露
6. 自动化测试方案
6.1 静态扫描工具链
推荐工具组合:
- ESLint插件检测危险函数
- DependencyCheck检查第三方库漏洞
- 自定义规则扫描敏感信息
配置示例(.eslintrc):
{ "rules": { "no-eval": "error", "no-unsafe-innerhtml": "error" }, "plugins": ["security"] }6.2 动态Fuzz测试
使用Python脚本模拟异常输入:
import requests test_cases = [ {"input": "' OR 1=1 --", "type": "SQLi"}, {"input": "<script>alert(1)</script>", "type": "XSS"} ] for case in test_cases: res = requests.post(api_url, json={"param": case["input"]}) analyze_response(res, case["type"])7. 企业级防护建议
7.1 代码混淆方案
- 启用微信官方混淆:
// project.config.json { "setting": { "minified": true, "uglifyFileName": true } }- 自定义字符串加密:
function _0xad3b(d) { return Buffer.from(d, 'hex').toString() } const api = _0xad3b('68747470733a2f2f6170692e6578616d706c652e636f6d')7.2 服务端防护策略
- 接口签名验证:
def verify_signature(request): nonce = request.headers.get('X-Nonce') timestamp = request.headers.get('X-Timestamp') sig = request.headers.get('X-Signature') local_sig = hmac.new(API_KEY, f"{nonce}{timestamp}".encode()).hexdigest() return hmac.compare_digest(sig, local_sig)- 请求频率限制:
limit_req_zone $binary_remote_addr zone=api:10m rate=100r/m;8. 测试环境搭建要点
8.1 安卓真机配置
- 开发者选项开启USB调试
- 刷入Magisk获取root权限
- 安装TrustMeAlready模块绕过证书锁定
8.2 iOS设备准备
- 越狱设备安装Cydia
- 部署SSL Kill Switch2
- 配置iproxy端口转发:
iproxy 2222 22 ssh -p 2222 root@localhost9. 法律合规边界
- 测试前必须获得书面授权
- 禁止披露发现的漏洞细节
- 报告需包含风险等级评估
- 遵守《网络安全法》相关规定
关键提示:所有技术方案仅限授权测试使用,商业小程序应关注微信官方安全规范,定期进行第三方安全审计