安全测试听起来是安全团队的事,但移动端有一大半安全问题测试工程师先撞上:证书固定让抓包失败、测试包里混进生产密钥、权限弹窗被自动点了"允许"。这篇讲测试视角的移动端安全测试——不追求红蓝对抗的深度,目标是让安全问题在测试阶段暴露。
一、抓包:测试安全的第一步,也是第一道坎
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
| def check_permissions_apk(apk_path): declared = apkanalyze(apk_path) 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"一样的常规产出——有检查单、有自动化、有报告,而不是上线后靠安全团队事后补救。