intercepting mobile app traffic is the first step in any mobile bug bounty engagement. mitmproxy is my go-to — it's free, scriptable, and works on both android and ios. here's the setup i use every time.
install it:
$ pip install mitmproxy $ mitmproxy --version
start the proxy. by default it runs on port 8080:
$ mitmproxy -p 8080
now configure your device to use the proxy. your laptop and phone need to be on the same network. find your local ip:
$ ifconfig | grep "inet " | grep -v 127.0.0.1 # inet 192.168.1.42 ...
on your phone, go to wifi settings, set the proxy to manual, enter your ip and port 8080. open a browser and navigate to mitm.it — this page serves the mitmproxy CA certificate.
download and install the cert. on android, this gets you user-level interception which works for most browser traffic. but apps targeting api 24+ only trust system-level certs by default.
to install as a system cert on a rooted android device:
# copy the cert from ~/.mitmproxy/ $ hashed_name=$(openssl x509 -inform PEM \ -subject_hash_old \ -in ~/.mitmproxy/mitmproxy-ca-cert.cer \ | head -1) $ cp ~/.mitmproxy/mitmproxy-ca-cert.cer $hashed_name.0 # push to device system cert store $ adb root $ adb remount $ adb push $hashed_name.0 /system/etc/security/cacerts/ $ adb shell chmod 644 /system/etc/security/cacerts/$hashed_name.0 $ adb reboot
after reboot, mitmproxy's cert is trusted at the system level. apps that don't implement certificate pinning will now send all traffic through your proxy — no complaints.
one caveat: this system-cert method works on android 13 and below. on android 14+ the trust store moved into the conscrypt apex and /system is read-only under verity, so adb remount + pushing to /system/etc/security/cacerts/ won't stick. on 14+ you either patch the apex cert store (rooted, more involved) or — usually easier — skip the system cert and use frida to disable pinning instead (covered in the jadx + frida post).
for apps that do implement pinning, you'll need frida to bypass it (covered in the jadx + frida post). but the proxy setup stays the same.
some useful mitmproxy flags i use constantly:
# only intercept specific domains $ mitmproxy --set intercept="~d api.target.com" # dump traffic to a file for later analysis $ mitmdump -w traffic.flow # replay saved traffic $ mitmdump -r traffic.flow # run with a custom script (e.g. log all auth tokens) $ mitmproxy -s log_tokens.py
speaking of scripts — mitmproxy's python api is where it gets really powerful. here's a quick addon that logs every authorization header it sees:
# log_tokens.py from mitmproxy import http def request(flow: http.HTTPFlow): auth = flow.request.headers.get("Authorization") if auth: print(f"[+] {flow.request.url}") print(f" Token: {auth}")
run it and every request with an auth header gets logged. useful for understanding how an app handles sessions, token refresh, and multi-account flows.
that's the core setup. proxy running, cert installed, traffic flowing. from here you can start mapping endpoints, fuzzing parameters, and looking for the real bugs.