# Miniprogram Security

> 当目标为微信/支付宝/抖音/百度等小程序（含微信云开发/云函数）、需要小程序包获取与反编译、appid/appsecret/接口提取、微信登录链/支付/越权/WebView/rich-text 渲染/云开发漏洞挖掘时调用。负责小程序全生命周期深度挖掘：包还原 → 代码审计 → 接口与密钥提取 → 登录/支付/越权/渲染/云开发专项 → 验证要点。命中场景：openid 替换越权、code 登录绕过、支付金额篡改、云函数未授权、web-view/rich-text XSS。

- Skill: `zhaji2333/miniprogram-security` (Agent Skill)
- Install (CLI): `npx skillmds@latest add zhaji2333/miniprogram-security`
- Raw SKILL.md: https://api.skillmd.com/api/skills/zhaji2333/miniprogram-security/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: zhaji2333 (https://skillmd.com/u/zhaji2333)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/zhaji2333/miniprogram-security

---


# miniprogram-security — 小程序专项深度挖掘

> **与 `android-security-audit` 的分工**：本技能专注 **小程序（微信/支付宝/抖音/百度）与微信云开发**；Android APK 组件安全见 `android-security-audit`。小程序与 APP 后台接口常同源，两技能可联动：先从 APP/小程序提取后端域名，再统一测接口。

## 何时调用（触发条件）

- 目标是微信/支付宝/抖音/百度/QQ 小程序
- 拿到小程序包（.wxapkg / 分包 / 反编译产物），需要还原源码
- 需要提取接口清单、appid/appsecret、云开发配置、加密/签名逻辑
- 发现微信登录链（wx.login code）、支付、openid/用户 ID 可控、未授权接口
- 发现 web-view / rich-text / JSBridge / 分享跳转 等前端渲染点
- 目标是微信云开发（云函数/云数据库/云存储）

## 快速开始（5 分钟出第一个接口/凭证）

```bash
# Step 1: 定位小程序包（PC 微信缓存目录）
# 微信/WeChat Files/Applet/<appid>/ 下 *.wxapkg（含分包）
# 或开发者工具/手机抓包/第三方平台获取

# Step 2: 反编译
# wxappUnpacker / unveilr / CrackMinApp 解包，得到 app.js、app.json、pages/、utils/、cloudfunctions/

# Step 3: 提取敏感信息与接口（高优先级）
grep -rniE "appid|appsecret|secret|access_key|secret_key|token" <解包目录>/
grep -rEoh "https?://[a-zA-Z0-9._/-]+" <解包目录>/ | sort -u          # 后端/业务域名
grep -rn "wx.request|wx.cloud.callFunction|request\(" <解包目录>/ | head -50  # 接口与云函数

# Step 4: 优先验证
# openid 可控 → 替换他人 openid 测越权；登录 code → 重放/替换；支付参数 → 金额篡改
```

---

## 一、包获取与反编译

**获取途径**
- **PC 微信**：`WeChat Files/Applet/<appid>/` 下 `.wxapkg` 缓存（主包+分包），需先在小程序里打开过
- **微信开发者工具**：导入源码调试（拿到项目源码的场景）
- **手机抓包**：HTTP(S) 代理 + 小程序包下载接口（配合证书安装）
- **第三方平台**：小程序包下载站、GitHub 泄露、历史版本
- **其他平台**：支付宝（.axml）、抖音、百度（.swan）结构类似，解包工具对应适配

**反编译工具**
```
wxappUnpacker        # 经典解包，还原 app.js/pages 结构
unveilr              # 较新，支持分包/新版格式
CrackMinApp          # 微信小程序一键解包
```
- 解包产物结构：`app.js`（全局逻辑）、`app.json`（页面/权限配置）、`pages/*`（页面）、`utils/*`、`project.config.json`、`cloudfunctions/`（云函数目录）
- 新版分包需先解主包再按 `app.json` 的 `subpackages` 配置逐分包解
- 压缩混淆的 JS：先用 js-beautify/反混淆还原，再搜索关键字

**还原度确认**：解包后核对 `app.json` 页面数与线上功能是否对应，确认还原完整再开始审计。

---

## 二、静态审计重点（代码层面）

**app.js / 全局逻辑**
- 全局接口封装、请求拦截器（看统一鉴权头怎么带的：token？openid？自定义签名？）
- 登录流程：`wx.login()` → code → 后端换 session/token 的完整链路
- 全局变量：appid、环境 env、后台域名、加密密钥

**敏感信息（重点上报项，联动 `recon-js-analysis`）**
- `appid`（正常）、**`appsecret` 出现在前端 = 配置错误/泄露**（后端才应持有）→ 上报并深挖（可换取 access_token 调接口）
- 云开发 env ID、腾讯云 SecretId/SecretKey、OSS/存储桶密钥、内网/后台域名
- 提取的 URL/IP/域名 → 提醒用户关注：可能是 APP/小程序后台接口，进入资产测绘

**接口清单提取**
- `wx.request({url: ...})` / `wx.cloud.callFunction({name: ...})` / `request(` 全部列出
- 参数结构、鉴权方式（header 里的 token/自定义头）、加密参数
- 隐藏接口：注释掉的、条件分支里的、旧版本接口

**渲染与组件**
- `web-view` 组件的 `src` 是否可控
- `rich-text` 组件的 `nodes` 是否渲染用户/AI 输入（XSS）
- 自定义 JSBridge / `wx.miniProgram.postMessage`、`navigateToMiniProgram` 跳转参数

---

## 三、场景表（漏洞全景）

| 场景 | 漏洞类型 | 挖掘要点 |
|---|---|---|
| 微信登录链 | 登录绕过/任意用户登录 | code→session_key→凭证；openid 参数可控、code 重放、session_key 泄露 |
| 支付/订单/退款 | 金额篡改/重复支付/回调绕过 | 下单金额参数可控、回调验签缺失、重复回调、退款金额 |
| 越权/IDOR | openid/用户 ID 替换 | 接口凭证绑定不严、ID 可遍历 |
| 未授权接口 | 敏感数据批量泄露 | 接口无鉴权/鉴权可绕过 |
| web-view | 任意 URL 加载/钓鱼 | src 可控、无域名白名单 |
| rich-text | XSS | nodes 渲染 HTML 无净化（含 AI 输出，联动 `xss-frontend-security`） |
| JSBridge/postMessage | 敏感能力调用 | 无白名单校验 |
| 云开发 | 云函数未授权/数据越权 | callFunction 任意调用、云数据库权限过大、云存储公开 |
| 本地存储 | 敏感信息泄露 | wx.setStorage 明文 token/密钥/手机号 |
| 分享/跳转 | 开放重定向/钓鱼 | 分享参数可控、navigateToMiniProgram 参数注入 |
| 获取用户信息 | 凭证泄露 | getPhoneNumber/getUserProfile 返回值被滥用/回显 |
| 短信/验证码 | 轰炸/绕过 | 无频率限制、验证码可绕过（与 `auth-access-control` 联动） |

---

## 四、微信登录链专项（最经典，先测）

**正常流程**：`wx.login()` 拿 `code` → 后端调 `code2session` 换 `openid/session_key` → 返回自定义 token。

**攻击面（按优先级）**
1. **openid 参数可控**（最常出洞）：后端把 `openid` 当请求参数接收（`{"openid":"xxx"}` 直接换 token）→ 填他人 openid = **任意用户登录**
2. **code 重放**：同一 code 可多次换取 token；code 未绑定会话/设备
3. **session_key 泄露**：后端把 session_key 返回给前端 → 可解密手机号等敏感数据
4. **token 可篡改**：自定义 token 里含 openid/user_id 明文可改（JWT 弱密钥/无签名，联动 `auth-access-control`）
5. **注册即登录**：注册接口直接返回已登录态，可批量注册撞已有 openid

**验证方法**
```
正常：自己的 code 登录 → 拿 token
A/B：把请求里的 openid 换成 B 的 → 若拿到 B 的会话/数据 → 任意用户登录/越权成立
重放：同一个 code 发两次 → 两次都能拿 token → 重放成立
```

---

## 五、支付逻辑专项

- **下单金额**：`total_fee`/`amount` 参数可控、负数、0.01、类型混淆
- **回调验签**：支付回调 `notify` 是否验签（MD5/签名比对）；不验签 → 伪造支付成功通知
- **重复回调**：同订单重复通知、幂等缺失 → 重复发货/重复入账
- **退款**：退款金额/次数可控、退款到他人账户
- **签名机制**：参数拼接 + appsecret 签名，参数顺序/编码差异绕过（与 `business-logic-race` / `auth-access-control` 联动）

---

## 六、云开发/云函数专项

- **云函数未鉴权**：`wx.cloud.callFunction({name:"任意函数名"})` 直接调用，函数内无 `cloud.getWXContext().OPENID` 身份校验 → 任意用户调管理员逻辑
- **云数据库权限**：默认权限（所有用户可读/可写）、`where` 条件可控 → 读他人数据、改他人记录
- **云存储**：公开读桶、可列举对象
- **环境切换**：env ID 可控 → 跨环境访问
- 验证：`wx.cloud.callFunction` 用他人 openid 上下文调用敏感函数，看是否拒绝

---

## 七、前端渲染 XSS 专项（web-view / rich-text）

**web-view**
- `src` 可控 → 加载任意 URL（钓鱼/恶意页面）；`src` 域名白名单可绕过（相似域名、URL 解析差异）
- 与 APP 内 WebView 同源风险：加载官方域页面 + JSBridge 注入（联动 `xss-frontend-security` 跳转型 XSS）

**rich-text**
- `nodes` 属性渲染 HTML 无净化 → `<img onerror>` / `<a href="javascript:">` 在 webview 内执行
- AI 输出/聊天记录进 rich-text 渲染 → AI 输出型存储 XSS（联动 `xss-frontend-security` 四 + `ai-llm-agent-security` 3.6）

**JSBridge / postMessage**
- `wx.miniProgram.postMessage` 到 App 端消息处理无白名单
- `navigateToMiniProgram` 参数注入（跳转任意小程序）

---

## 八、分享/跳转专项

- 分享链接/卡片参数可控 → 开放重定向、钓鱼、参数注入
- 页面 `onShareAppMessage` 的 path 参数拼接 → 跳转内部功能（未授权页面）
- 扫码进入（scheme 参数）→ 与 Deep Link 类似，参数驱动内部跳转

---

## 九、验证要点

- 反编译还原度确认后再审计，防漏接口
- 接口全方法测试（GET/POST/PUT/DELETE）+ 无 token / 伪造 token / 他人 token 对比
- **登录链 A/B 交叉证明**：A 凭证访问 B 数据才算越权成立（只读自己数据不报）
- 支付回调重放/验签缺失：真实回调触发一次 → 重放 → 观察状态变化
- 云函数：换 openid 上下文调用敏感函数
- 渲染 XSS：真实触发（web-view 加载恶意 URL / rich-text 弹窗截图）
- 证据链：Burp 请求块 + 截图 + 影响证明；正式报告走 `report` 技能

## 十、修复建议

- **openid/session_key 一律服务端获取**，不信任前端传参；接口按服务端解析的身份鉴权
- code 一次性绑定会话、防重放；token 强签名、短时效
- 支付回调强制验签 + 幂等；金额服务端定价，不信任客户端参数
- 云函数入口做 `getWXContext().OPENID` 身份校验；云数据库按最小权限配置 + openid 过滤
- rich-text 渲染白名单净化（DOMPurify 适配小程序）；web-view src 白名单严格校验
- 本地存储不存明文 token/密钥；敏感接口加频率限制
- appsecret/云密钥严禁进前端包，扫描泄露并回收

---

## 联动

- 接口/鉴权/越权 → `api-protocol-security` / `auth-access-control`
- 支付/竞态 → `business-logic-race`
- 后端域名/appid/appsecret 提取 → `recon-js-analysis`
- rich-text/AI 输出渲染 XSS → `xss-frontend-security`（四）+ `ai-llm-agent-security`（3.6）
- 正式报告 DOCX → `report`

