mitmproxy Cheatsheet - Modes, Filters & HTTPS

Browser DevTools only sees what your own browser sent; to see other apps' HTTPS traffic you need a MITM proxy. This reference covers mitmproxy/mitmdump/mitmweb modes and ports, filter expressions, flow interception/editing, addon scripts, and the CA-cert install that decrypts HTTPS. Use it when debugging a mobile app, an old client, or a scheduled job that doesn't go through the browser. After reading you can capture, filter and even rewrite live API calls.

Dev Tools·37 commands·Last updated 2026-07-21
mitmproxyPacket CaptureProxy

Typical Use Case

For backend and client developers reproducing production issues: point a phone or test device at a local mitmproxy, locate one flow among hundreds with filter expressions, inspect headers and bodies, then modify and replay when needed. mitmweb lets non-CLI colleagues watch along, while mitmdump suits scripts and CI traffic capture. This sheet covers the startup modes (regular, transparent, upstream), combining filter expressions, interactive keybindings, scripted modification, and the CA certificate install paths.

Startup & Modes 7

mitmproxy
Start the interactive UI
mitmweb
Start the Web UI
mitmdump
Command-line mode (like tcpdump)
mitmproxy -p 8080
Specify a port
mitmproxy --mode transparent
Transparent proxy mode
mitmproxy --mode upstream:http://proxy:8080
Upstream proxy mode
mitmproxy --listen-host 0.0.0.0
Listen on all addresses

Filter Expressions 11

~u example.com
URL contains example.com
~d example.com
Domain contains example.com
~m GET
Method is GET
~c 200
Status code 200
~h "Content-Type: json"
Header contains
~b "error"
Request or response body contains
~q
Requests only
~s
Responses only
~t "text/html"
Content-Type matches
~u example.com & ~m GET
Combined filter (AND)
~u example.com | ~u test.com
Combined filter (OR)

Interactive Operations 10

?
View help
q
Quit
e
Edit request/response
r
Replay request
w
Save to file
W
Stream-save to file
/
Search
n
Create new request
I
Intercept mode toggle
F
Set focus-follow

Scripting & Modification 5

mitmproxy -s script.py
Load a script
mitmdump -s script.py -w outfile
Script + save traffic
mitmproxy --set blocklist=example.com
Block a domain
mitmproxy --set modify_headers="~q|Host:example.com"
Modify request headers
mitmproxy --set modify_body="~q|regex|replace"
Modify request body

HTTPS Certificates 4

mitmproxy --set ssl_insecure=true
Skip upstream cert verification
Visit http://mitm.it to download the cert
Download the CA cert on the client
~/.mitmproxy/mitmproxy-ca-cert.pem
CA certificate path
security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain cert.pem
Install cert on macOS

Parameter matrix

ParameterEffectExample
-p / --listen-hostPort and address to bind; it listens on localhost only unless --listen-host 0.0.0.0 is setmitmproxy --listen-host 0.0.0.0
~u / ~d / ~m / ~cFilter by URL, domain, method and status code; & combines as AND and | as OR~u example.com & ~m GET
--set modify_headers / modify_bodyEdit headers and bodies without a script, spelled filter|Header:value or filter|regex|replacementmitmproxy --set modify_body="~q|regex|replace"
-s script.py / -w outfileLoad an addon script and, with -w, save the traffic to a file for later analysismitmdump -s script.py -w outfile

Common pitfalls

SymptomAfter configuring the proxy the app is completely offline and no HTTPS page loads.

CauseThe client has no CA certificate, so the intercepted TLS handshake fails validation.

FixHave the client visit http://mitm.it to download it, or install and trust ~/.mitmproxy/mitmproxy-ca-cert.pem.

SymptomA phone on the LAN cannot reach the proxy and no flows show up.

Causemitmproxy binds to the loopback interface only.

FixAdd --listen-host 0.0.0.0 (with -p for the port) and confirm the client is on the same subnet with the firewall open.

SymptomThe app reports SSL handshake failed / network error while CLI capture works.

CauseThe app pins certificates and only trusts system-installed CAs.

FixDisable pinning in the test build, capture decrypted traffic instead, and allow upstream self-signed certs with --set ssl_insecure=true.

Symptommodify_body was set but the captured body is unchanged.

Causemodify_body only touches matching flows and needs an explicit request or response side.

FixConstrain the direction with ~q / ~s or a fuller filter, or write an addon with -s script.py for precise control.

Troubleshooting

  1. 1Confirm the proxy port is really listening

    mitmproxy -p 8080

    Point the client proxy at this host IP and port 8080; if nothing connects, start here.

  2. 2Blacklist a suspicious domain to prove interception works

    mitmproxy --set blocklist=example.com

    Matching requests get blocked, which confirms the proxy path itself is functioning.

  3. 3Rewrite a suspicious request header and watch the client react

    mitmproxy --set modify_headers="~q|Host:example.com"

    The syntax is filter|Header:value; replay with r in the interactive UI to see the effect immediately.

Command Examples

Launch modes and the listen address

mitmproxy mitmweb mitmdump mitmproxy -p 8080 mitmproxy --listen-host 0.0.0.0 mitmproxy --mode transparent mitmproxy --mode upstream:http://proxy:8080

Loopback is the default, so external devices require an explicit --listen-host 0.0.0.0; mitmdump is the mode that fits scripting and CI.

Filter expressions and how to combine them

~u example.com ~d example.com ~m GET ~c 200 ~b "error" ~q ~s ~u example.com & ~m GET ~u example.com | ~u test.com

& means AND and | means OR, while ~q keeps only requests and ~s only responses, cutting the noise down to the traffic you care about.

Rewriting headers and bodies without a script

mitmproxy --set modify_headers="~q|Host:example.com" mitmproxy --set modify_body="~q|regex|replace" mitmproxy --set blocklist=example.com mitmproxy --set ssl_insecure=true

The shape is filter|target|replacement: ~q scopes to requests, ~s to responses, and omitting the filter applies the rule to all traffic.

Scripted rewriting plus recording the traffic

mitmproxy -s script.py mitmdump -s script.py -w outfile

The -w flag records traffic to a file while dumping, which pays off when you replay it later; inside the UI, w and W save a single flow or stream continuously.

Common Pitfalls

  • Without --listen-host 0.0.0.0 mitmproxy only listens on loopback, so phones and test devices simply never show up in the flow list.
  • The proxy host configured on the device must be your LAN address; 127.0.0.1 on a phone points at the phone itself.
  • HTTPS capture requires installing and trusting the CA certificate from http://mitm.it on the client; the file lives at ~/.mitmproxy/mitmproxy-ca-cert.pem.
  • --mode transparent needs its own routing and firewall configuration, and getting it wrong cuts the client off from the network entirely.
  • A wrong scope prefix on modify_headers or modify_body, typing ~s where ~q was meant, makes the rewrite fail silently, so check that first.

Tips

  • HTTPS capture needs the mitmproxy CA cert installed on the client.
  • Transparent proxy mode needs iptables or routing; good for mobile capture.
  • Scripts are written in Python and can implement complex request modifications.

FAQ

My phone cannot reach the proxy on my machine. How do I narrow it down?

Three checks. By default mitmproxy listens on the loopback interface only, so --listen-host 0.0.0.0 is required to accept connections from other devices. Confirm the port with mitmproxy -p 8080, and make sure the proxy host entered on the device is your LAN address rather than 127.0.0.1. The device also needs the CA certificate installed, downloaded from http://mitm.it. HTTPS pages failing with an SSL handshake error while command-line capture works normally is the classic symptom of a device that has not installed or trusted ~/.mitmproxy/mitmproxy-ca-cert.pem.

Can filter expressions be combined, and what is the syntax?

Yes: join them with & for AND and | for OR. The single operators are ~u for URL, ~d for domain, ~m for method, ~c for status code, ~h for headers, ~b for request or response body, ~t for content type, ~q for requests only and ~s for responses only. For example ~u example.com & ~m GET narrows to GET requests on that domain, and ~u example.com | ~u test.com covers both domains. On the command line these expressions go into the mitmdump invocation, and inside the interactive UI the / search follows the same syntax.

Can I change a header or body without writing a script?

Use the modify_headers and modify_body options of --set, whose syntax is filter|target|replacement: mitmproxy --set modify_headers="~q|Host:example.com" rewrites a header, and mitmproxy --set modify_body="~q|regex|replace" rewrites the body with a regular expression. Omit the filter to apply the change to everything. The ~q prefix scopes the rule to requests and ~s scopes it to responses. If a change appears not to take effect, check that ~q was not written as ~s, or that unescaped characters in the pattern stopped the whole expression from matching.

How do I configure mitmproxy when there is already an upstream proxy?

Use --mode upstream:http://proxy:8080 to sit mitmproxy between the client and the upstream proxy, so you see both what the client sent and what came back. If the upstream certificate is itself problematic, such as a self-signed or incomplete chain, add --set ssl_insecure=true to skip upstream verification, otherwise the handshake fails outright. Transparent mode via --mode transparent needs its own routing or firewall setup and is the wrong choice when you only want to chain behind an existing proxy.

Once I have the traffic, how do I find the problem quickly?

In the interactive UI, use / to search for the flow, e to open the request or response editor and inspect the fields, r to replay the request and see whether it reproduces reliably, I to toggle intercept mode so only the selected flow gets through, and w and W to save a single flow or stream everything to disk for later analysis; ? lists every shortcut. To verify whether a domain is being blocked at all, use mitmproxy --set blocklist=example.com and watch how the client reacts.

Official References

Each command links to its official documentation below, so you can verify the latest usage and read deeper.

Maintained by LaoHand

Publicly updated on Jul 21, 2026, continuously proofread against official docs.

Contact Us

Wrong command or description? Send us corrections, business inquiries or product feedback by email.

Contact Us