mitmproxy脚本必须注册request等事件钩子才能拦截请求,未注册则脚本无效;修改请求需原地操作flow.request并适配content-type,真机抓包须正确安装并信任证书。

mitmproxy 脚本必须用 start 或 request 钩子才能拦截请求
mitmproxy 不是“启动就自动改包”,它靠事件钩子驱动。没注册 request 或 start,脚本加载了也等于没写。常见错误是只写了逻辑函数但没加装饰器,结果请求照常转发,毫无篡改痕迹。
实操建议:
- 必须用
@http.request(新版 mitmproxy 7+)或@addon+request方法注册;老版本用def request(flow):即可,但需确保函数名是request - 修改请求头、URL、body 必须在
flow.request上操作,不是新建对象;直接赋值会失败,要用flow.request.headers["X-Test"] = "1"这类原地修改 - 如果想只处理特定域名,开头加判断:
if "api.example.com" in flow.request.host:,避免误改其他流量
篡改 POST 请求 body 要先确认编码,别硬塞字符串
很多脚本一上来就写 flow.request.text = '{"id": 123}',结果服务端收不到或报 400 —— 因为原始请求可能是 application/x-www-form-urlencoded,而你塞的是 JSON 字符串,Content-Type 没同步改,服务器按表单解析自然出错。
实操建议:
- 先检查
flow.request.headers.get("content-type", ""),区分application/json、application/x-www-form-urlencoded、multipart/form-data - JSON 类型:用
flow.request.json = {"id": 123}(自动序列化+设 header),比手动改text安全 - 表单类型:用
flow.request.urlencoded_form["token"] = "abc",别碰text;否则要自己拼a=1&b=2并重算Content-Length - 二进制或未知类型:优先用
flow.request.content = new_bytes,并手动更新Content-Length头
mitmdump 命令行参数顺序影响脚本加载和代理行为
mitmdump -s script.py -p 8080 看似没问题,但如果你加了 -R http://target(上游代理)或 --set block_global=false,顺序错了就会静默失效,甚至脚本根本不执行。
实操建议:
- 脚本参数
-s必须放在最前面,例如:mitmdump -s script.py -p 8080 -R http://10.0.0.1:8080 - 启用 HTTPS 解密必须加
--set ssl_insecure=true(跳过证书校验)和--set confdir=./mitmconf(指定证书目录),否则安卓/iOS App 的请求直接被断连 - 想看控制台实时日志,加
-v;想保存所有流量到文件,加-w dump.mitm,这个文件后续可用mitmweb -r dump.mitm回放分析
Android/iOS 真机抓包时,证书信任是最大拦路虎
mitmproxy 默认生成的证书在桌面浏览器里点几下就能信任,但在手机上——尤其是 iOS 17+ 和 Android 10+——不手动安装并「完全信任」证书,所有 HTTPS 请求都会失败,且错误不报在 mitmproxy 日志里,只显示 502 Bad Gateway 或连接超时。
实操建议:
- 首次运行
mitmdump -s script.py后,访问http://mitm.it(注意是 HTTP),选对应系统下载并安装证书 - iOS:设置 → 已下载描述文件 → 安装 → 设置 → 关于本机 → 证书信任设置 → 开启 mitmproxy 证书
- Android:设置 → 安全 → 加密与凭据 → 安装证书 → 选择下载的
mitmproxy-ca-cert.pem(需先转成 .crt 或 .cer,用openssl x509 -in mitmproxy-ca-cert.pem -out cert.crt) - 某些 App(如微信、银行类)会做证书固定(Certificate Pinning),mitmproxy 无法绕过,此时脚本再完善也抓不到包
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











