appsec · security research
~
────────────────────────────────
← back

mitmproxy setup for mobile interception

mar 1, 2026 · 4 min read

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.