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.
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
mitmproxymitmwebmitmdumpmitmproxy -p 8080mitmproxy --mode transparentmitmproxy --mode upstream:http://proxy:8080mitmproxy --listen-host 0.0.0.0Filter Expressions 11
~u example.com~d example.com~m GET~c 200~h "Content-Type: json"~b "error"~q~s~t "text/html"~u example.com & ~m GET~u example.com | ~u test.comInteractive Operations 10
?qerwW/nIFScripting & Modification 5
mitmproxy -s script.pymitmdump -s script.py -w outfilemitmproxy --set blocklist=example.commitmproxy --set modify_headers="~q|Host:example.com"mitmproxy --set modify_body="~q|regex|replace"HTTPS Certificates 4
mitmproxy --set ssl_insecure=trueVisit http://mitm.it to download the cert~/.mitmproxy/mitmproxy-ca-cert.pemsecurity add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain cert.pemParameter matrix
| Parameter | Effect | Example |
|---|---|---|
-p / --listen-host | Port and address to bind; it listens on localhost only unless --listen-host 0.0.0.0 is set | mitmproxy --listen-host 0.0.0.0 |
~u / ~d / ~m / ~c | Filter by URL, domain, method and status code; & combines as AND and | as OR | ~u example.com & ~m GET |
--set modify_headers / modify_body | Edit headers and bodies without a script, spelled filter|Header:value or filter|regex|replacement | mitmproxy --set modify_body="~q|regex|replace" |
-s script.py / -w outfile | Load an addon script and, with -w, save the traffic to a file for later analysis | mitmdump -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
1Confirm the proxy port is really listening
mitmproxy -p 8080Point the client proxy at this host IP and port 8080; if nothing connects, start here.
2Blacklist a suspicious domain to prove interception works
mitmproxy --set blocklist=example.comMatching requests get blocked, which confirms the proxy path itself is functioning.
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:8080Loopback 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=trueThe 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 outfileThe -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