移动端安全测试入门:从抓包到证书固定

安全测试听起来是安全团队的事,但移动端有一大半安全问题测试工程师先撞上:证书固定让抓包失败、测试包里混进生产密钥、权限弹窗被自动点了"允许"。这篇讲测试视角的移动端安全测试——不追求红蓝对抗的深度,目标是让安全问题在测试阶段暴露

一、抓包:测试安全的第一步,也是第一道坎

1. 先解决"抓不到"

App 抓包失败 90% 是证书固定(SSL Pinning)

1
2
3
4
5
6
7
8
9
10
抓包失败排查顺序:
1. 系统代理没配 → 配 mitmproxy 代理(Android: 设置→WLAN→代理)
2. CA 证书没装 → 装 mitmproxy 根证书
Android 7+:用户证书默认不信任 → 要 root 装到 /system/etc/security/cacerts/
或用 adb:adb root && adb remount && adb push mitmproxy-ca.pem /system/etc/security/cacerts/
3. 证书固定 → App 只认自己的公钥,换证书直接断连
解法(按代价排序):
- 测试包关闭 pinning(找开发要 debug 开关)✅ 首选
- Frida hook 掉 OkHttp/CertificatePinner(Android)
- iOS 用 frida-ios + objection:objection explore --unpin-certs

团队约定:所有测试包必须有"调试模式"(关 pinning + 开日志),这不是妥协——生产包才需要 pinning,测试包开着等于让所有测试都跑不动。

2. 抓包要抓什么

不是抓完看个响,要有检查单:

检查项 风险 判定
明文 HTTP 传输 中间人窃听 除白名单(如第三方 SDK 回退)外,全部 HTTPS
敏感字段明文 密码/银行卡/身份证入包 登录接口 password 字段必须加密(至少一次性 salt)
证书固定是否生效 抓包即窃听 生产包用 Frida 尝试 unpin,应失败
响应里带敏感信息 过度暴露 接口不该返回的字段(如完整卡号)出现即报

二、权限与数据:移动端独有的检查面

1. 权限最小化

1
2
3
4
5
6
7
# 自动化检查:声明的权限 vs 实际申请的权限
def check_permissions_apk(apk_path):
declared = apkanalyze(apk_path) # 静态:manifest 声明
requested = runtime_collect(driver) # 动态:实际触发的权限弹窗
# 声明了但从不申请 = 冗余(可要求移除)
# 申请了但没声明 = 直接装不上(编译期就暴露)
# 高危权限(通讯录/位置/相机)必须逐条有业务理由

经验:应用市场审核最卡的也是这块,测试阶段提前清一遍"用不到的权限",比上线被拒划算。

2. 本地存储检查

移动端最容易被忽略的泄露面是本地

  • SharedPreferences / UserDefaults 里存没存明文 token、密码;
  • 崩溃日志(crash log)里带没带业务数据——某次线上事故就是 crash 上报把用户手机号发了出去;
  • 截屏/录屏保护:金融类 App 应设 FLAG_SECURE(截屏黑屏);
  • 卸载残留:卸载后 adb shell/data/data/<pkg>/ 是否清干净。

三、与 UI 自动化结合:安全用例进回归

安全检查不是一次性的专项,可自动化的部分进日常回归

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@pytest.mark.security
def test_login_password_not_in_plaintext(driver, proxy):
"""登录流量中密码不得明文出现"""
with proxy.capture() as flow:
login(driver, "tester", "S3cret!")
assert "S3cret!" not in flow.raw_request
assert "S3cret!" not in flow.raw_response

@pytest.mark.security
def test_token_stored_encrypted(driver):
"""token 本地存储不得明文可读"""
login(driver, "tester", "S3cret!")
sp = read_shared_prefs(driver, "auth.xml")
assert "token=" not in sp and not looks_like_jwt(sp.get("t"))

四、小结

测试视角的移动端安全四件事:抓包(先解决 pinning)传输检查单(HTTPS/加密/最小暴露)本地存储检查(明文 token/日志/截屏/残留)安全用例进回归。目标是让"安全问题"变成和"功能 bug"一样的常规产出——有检查单、有自动化、有报告,而不是上线后靠安全团队事后补救。