W↓
All docs
🔑
Sign Up/Sign In
docs.mitmproxy.org/stable/concepts/
Public Link
May 27, 2025, 4:33:21 AM - complete - 75.2 kB
Created by:
****ad@vlad.studio
Starting URLs:
https://docs.mitmproxy.org/stable/concepts/how-mitmproxy-works/
CSS Selector:
main
Crawl Prefixes:
https://docs.mitmproxy.org/stable/concepts/
## Page: https://docs.mitmproxy.org/stable/concepts/how-mitmproxy-works/ Edit on GitHub # How mitmproxy works Mitmproxy is an enormously flexible tool. Knowing exactly how the proxying process works will help you deploy it creatively, and take into account its fundamental assumptions and how to work around them. This document explains mitmproxy’s proxy mechanism in detail, starting with the simplest unencrypted explicit proxying, and working up to the most complicated interaction -transparent proxying of TLS-protected traffic1 in the presence of Server Name Indication. ## Explicit HTTP Configuring the client to use mitmproxy as an explicit proxy is the simplest and most reliable way to intercept traffic. The proxy protocol is codified in the HTTP RFC, so the behaviour of both the client and the server is well defined, and usually reliable. In the simplest possible interaction with mitmproxy, a client connects directly to the proxy, and makes a request that looks like this: GET http://example.com/index.html HTTP/1.1 This is a proxy GET request - an extended form of the vanilla HTTP GET request that includes a schema and host specification, and it includes all the information mitmproxy needs to proceed.  #### Explicit 1. The client connects to the proxy and makes a request. 2. Mitmproxy connects to the upstream server and simply forwards the request on. ## Explicit HTTPS The process for an explicitly proxied HTTPS connection is quite different. The client connects to the proxy and makes a request that looks like this: CONNECT example.com:443 HTTP/1.1 A conventional proxy can neither view nor manipulate a TLS-encrypted data stream, so a CONNECT request simply asks the proxy to open a pipe between the client and server. The proxy here is just a facilitator - it blindly forwards data in both directions without knowing anything about the contents. The negotiation of the TLS connection happens over this pipe, and the subsequent flow of requests and responses are completely opaque to the proxy. ### The MITM in mitmproxy This is where mitmproxy’s fundamental trick comes into play. The MITM in its name stands for Man-In-The-Middle - a reference to the process we use to intercept and interfere with these theoretically opaque data streams. The basic idea is to pretend to be the server to the client, and pretend to be the client to the server, while we sit in the middle decoding traffic from both sides. The tricky part is that the Certificate Authority system is designed to prevent exactly this attack, by allowing a trusted third-party to cryptographically sign a server’s certificates to verify that they are legit. If this signature doesn’t match or is from a non-trusted party, a secure client will simply drop the connection and refuse to proceed. Despite the many shortcomings of the CA system as it exists today, this is usually fatal to attempts to MITM a TLS connection for analysis. Our answer to this conundrum is to become a trusted Certificate Authority ourselves. Mitmproxy includes a full CA implementation that generates interception certificates on the fly. To get the client to trust these certificates, we register mitmproxy as a trusted CA with the device manually. ### Complication 1: What’s the remote hostname? To proceed with this plan, we need to know the domain name to use in the interception certificate - the client will verify that the certificate is for the domain it’s connecting to, and abort if this is not the case. At first blush, it seems that the CONNECT request above gives us all we need - in this example, both of these values are “example.com”. But what if the client had initiated the connection as follows: CONNECT 10.1.1.1:443 HTTP/1.1 Using the IP address is perfectly legitimate because it gives us enough information to initiate the pipe, even though it doesn’t reveal the remote hostname. Mitmproxy has a cunning mechanism that smooths this over - upstream certificate sniffing. As soon as we see the CONNECT request, we pause the client part of the conversation, and initiate a simultaneous connection to the server. We complete the TLS handshake with the server, and inspect the certificates it used. Now, we use the Common Name in the upstream certificates to generate the dummy certificate for the client. Voila, we have the correct hostname to present to the client, even if it was never specified. ### Complication 2: Subject Alternative Name Enter the next complication. Sometimes, the certificate Common Name is not, in fact, the hostname that the client is connecting to. This is because of the optional Subject Alternative Name field in the certificate that allows an arbitrary number of alternative domains to be specified. If the expected domain matches any of these, the client will proceed, even though the domain doesn’t match the certificate CN. The answer here is simple: when we extract the CN from the upstream cert, we also extract the SANs, and add them to the generated dummy certificate. ### Complication 3: Server Name Indication One of the big limitations of vanilla TLS is that each certificate requires its own IP address. This means that you couldn’t do virtual hosting where multiple domains with independent certificates share the same IP address. In a world with a rapidly shrinking IPv4 address pool this is a problem, and we have a solution in the form of the Server Name Indication extension to the TLS protocols. This lets the client specify the remote server name at the start of the TLS handshake, which then lets the server select the right certificate to complete the process. SNI breaks our upstream certificate sniffing process, because when we connect without using SNI, we get served a default certificate that may have nothing to do with the certificate expected by the client. The solution is another tricky complication to the client connection process. After the client connects, we allow the TLS handshake to continue until just **after** the SNI value has been passed to us. Now we can pause the conversation, and initiate an upstream connection using the correct SNI value, which then serves us the correct upstream certificate, from which we can extract the expected CN and SANs. ### Putting it all together Lets put all of this together into the complete explicitly proxied HTTPS flow.  #### Explicit HTTPS 1. The client makes a connection to mitmproxy, and issues an HTTP CONNECT request. 2. Mitmproxy responds with a `200 Connection Established`, as if it has set up the CONNECT pipe. 3. The client believes it’s talking to the remote server, and initiates the TLS connection. It uses SNI to indicate the hostname it is connecting to. 4. Mitmproxy connects to the server, and establishes a TLS connection using the SNI hostname indicated by the client. 5. The server responds with the matching certificate, which contains the CN and SAN values needed to generate the interception certificate. 6. Mitmproxy generates the interception cert, and continues the client TLS handshake paused in step 3. 7. The client sends the request over the established TLS connection. 8. Mitmproxy passes the request on to the server over the TLS connection initiated in step 4. ## Transparent HTTP When a transparent proxy is used, the connection is redirected into a proxy at the network layer, without any client configuration being required. This makes transparent proxying ideal for those situations where you can’t change client behaviour - proxy-oblivious Android applications being a common example. To achieve this, we need to introduce two extra components. The first is a redirection mechanism that transparently reroutes a TCP connection destined for a server on the Internet to a listening proxy server. This usually takes the form of a firewall on the same host as the proxy server - iptables on Linux or pf on OSX. Once the client has initiated the connection, it makes a vanilla HTTP request, which might look something like this: GET /index.html HTTP/1.1 Note that this request differs from the explicit proxy variation, in that it omits the scheme and hostname. How, then, do we know which upstream host to forward the request to? The routing mechanism that has performed the redirection keeps track of the original destination for us. Each routing mechanism has a different way of exposing this data, so this introduces the second component required for working transparent proxying: a host module that knows how to retrieve the original destination address from the router. In mitmproxy, this takes the form of a built-in set of modules that know how to talk to each platform’s redirection mechanism. Once we have this information, the process is fairly straight-forward.  #### Transparent 1. The client makes a connection to the server. 2. The router redirects the connection to mitmproxy, which is typically listening on a local port of the same host. Mitmproxy then consults the routing mechanism to establish what the original destination was. 3. Now, we simply read the client’s request… 4. … and forward it upstream. ## Transparent HTTPS The first step is to determine whether we should treat an incoming connection as HTTPS. The mechanism for doing this is simple - we use the routing mechanism to find out what the original destination port is. All incoming connections pass through different layers which can determine the actual protocol to use. Automatic TLS detection works for SSLv3, TLS 1.0, TLS 1.1, and TLS 1.2 by looking for a _ClientHello_ message at the beginning of each connection. This works independently of the used TCP port. From here, the process is a merger of the methods we’ve described for transparently proxying HTTP, and explicitly proxying HTTPS. We use the routing mechanism to establish the upstream server address, and then proceed as for explicit HTTPS connections to establish the CN and SANs, and cope with SNI.  #### Transparent HTTPS 1. The client makes a connection to the server. 2. The router redirects the connection to mitmproxy, which is typically listening on a local port of the same host. Mitmproxy then consults the routing mechanism to establish what the original destination was. 3. The client believes it’s talking to the remote server, and initiates the TLS connection. It uses SNI to indicate the hostname it is connecting to. 4. Mitmproxy connects to the server, and establishes a TLS connection using the SNI hostname indicated by the client. 5. The server responds with the matching certificate, which contains the CN and SAN values needed to generate the interception certificate. 6. Mitmproxy generates the interception cert, and continues the client TLS handshake paused in step 3. 7. The client sends the request over the established TLS connection. 8. Mitmproxy passes the request on to the server over the TLS connection initiated in step 4. ### Footnotes * * * 1. The use of “TLS” refers to both SSL (outdated and insecure) and TLS (1.0 and up) in the generic sense, unless otherwise specified. ↩︎ --- ## Page: https://docs.mitmproxy.org/stable/concepts/modes/ Edit on GitHub # Proxy Modes mitmproxy supports different proxy modes to capture traffic. You can use any of the modes with any of the mitmproxy tools (mitmproxy, mitmweb, or mitmdump). ### Recommended * Regular: The default mode. Configure your client(s) to use an HTTP(S) proxy. * Local Capture: Capture applications on the same device. * WireGuard: Capture external devices or individual Android apps. * Reverse: Put mitmproxy in front of a server. ### Advanced Modes * Transparent: Capture traffic with custom network routes. * TUN Interface: Create a virtual network device to capture traffic. * Upstream: Chain two HTTP(S) proxies. * SOCKS: Run a SOCKS5 proxy server. * DNS: Run a scriptable DNS server. ## Regular Proxy Mitmproxy’s regular mode is the simplest and the most robust to set up. If your target can be configured to use an HTTP proxy, we recommend you start with this. 1. Start `mitmproxy`, `mitmdump`, or `mitmweb`. You do not need to pass any arguments. 2. Configure your client to use mitmproxy by explicitly setting an HTTP proxy. By default, mitmproxy listens on port 8080. 3. Quick Check: You should already be able to visit an unencrypted HTTP site through the proxy. 4. Open the magic domain **mitm.it** and install the certificate for your device. ### Troubleshooting 1. If you do not see any traffic in mitmproxy, open mitmproxy’s event log. You should be seeing `client connect` messages in there. If you do not see `client connect` messages, your client does not reach the proxy at all: * You have maybe misconfigured the IP address or port. * Alternatively your wireless network may use _client isolation_, which prevents clients from communicating with one another. 2. There are applications that bypass the operating system’s HTTP proxy settings - Android applications are a common example. In these cases, you need to use mitmproxy’s WireGuard, Local Capture, or transparent modes. #### Network Topology If you are proxying an external device, your network will probably look like this:  The square brackets signify the source and destination IP addresses. Your client explicitly connects to mitmproxy and mitmproxy explicitly connects to the target server. ## Local Capture Local capture mode transparently captures traffic from applications running on the same device. You can capture everything on the current device, or only a particular process name or process ID (PID): mitmproxy --mode local # Intercept everything on this machine. mitmproxy --mode local:curl # Intercept cURL only. mitmproxy --mode local:42 # Intercept PID 42 only. Local capture is implemented using low-level operating system APIs, so interception is transparent and the targeted application is not aware of being proxied. If you are curious about implementation details, check out the announcement blog posts. Local capture is available on Windows, Linux, and macOS. #### Intercept Specs The target selection can be negated by prepending an exclamation mark: mitmproxy --mode local:!curl # Intercept everything on this machine but cURL. It is also possible to provide a comma-separated list: mitmproxy --mode local:curl,wget # Intercept cURL and wget only. mitmproxy --mode local:!curl,!wget # Intercept everything but cURL and wget. #### Local Capture Limitations on Linux * **Egress only:** mitmproxy will capture outbound connections only. For inbound connections, we recommend reverse proxy mode. * **Root privileges:** To load the BPF program, mitmproxy needs to spawn a privileged subprocess using `sudo`. For the web UI, this means that mitmweb needs to be started directly with `--mode local` on the command line to get a sudo password prompt. * **Kernel compatibility:** Our eBPF instrumentation requires a reasonably recent kernel. We officially support Linux 6.8 and above, which matches Ubuntu 22.04. * **Intercept specs:** Program names are matched on the first 16 characters only (based on the kernel’s TASK\_COMM\_LEN). * **Containers:** Capturing traffic from containers will fail unless they use the host network. For example, containers can be started with `docker/podman run --network host`. * **Windows Subsystem for Linux (WSL 1/2):** WSL is unsupported as eBPF is disabled by default. #### Local Capture Limitations on macOS * **Egress only:** mitmproxy will capture outbound connections only. For inbound connections, we recommend reverse proxy mode. ## WireGuard In WireGuard mode, mitmproxy starts a WireGuard VPN server. Devices can be connected using standard WireGuard client applications and mitmproxy will transparently intercept their traffic. 1. Start `mitmweb --mode wireguard`. 2. Install a WireGuard client on target device. 3. Import the WireGuard client configuration provided by mitmproxy. No additional routing configuration is required. The WireGuard server runs entirely in userspace, so no administrative privileges are necessary in this mode. ### Configuration #### WireGuard server By default, the WireGuard server will listen on port `51820/udp`, the default port for WireGuard servers. This can be changed by setting the `listen_port` option or by specifying an explicit port (`--mode wireguard@51821`). The encryption keys for WireGuard connections are stored in `~/.mitmproxy/wireguard.conf`. It is possible to specify a custom path with `--mode wireguard:path`. New keys will be generated automatically if the specified file does not yet exist. For example, to connect two clients simultaneously, you can run `mitmdump --mode wireguard:wg-keys-1.conf --mode wireguard:wg-keys-2.conf@51821`. #### WireGuard clients It is possible to limit the IP addresses for which traffic is sent over the WireGuard tunnel to specific ranges. In this case, the `AllowedIPs` setting in the WireGuard client configuration can be changed from `0.0.0.0/0` (i.e “route _all_ IPv4 traffic through the WireGuard tunnel”) to the desired ranges of IP addresses (this setting allows multiple, comma-separated values). For more complex network layouts it might also be necessary to override the automatically detected `Endpoint` IP address (i.e. the address of the host on which mitmproxy and its WireGuard server are running). ### Limitations #### Transparently proxying mitmproxy host traffic With the current implementation, it is not possible to proxy all traffic of the host that mitmproxy itself is running on, since this would result in outgoing WireGuard packets being sent over the WireGuard tunnel themselves. #### Limited support for IPv6 traffic The WireGuard server internal to mitmproxy supports receiving IPv6 packets from client devices, but support for proxying IPv6 packets themselves is still limited. For this reason, the `AllowedIPs` setting in generated WireGuard client configurations does not list any IPv6 addresses yet. To enable the incomplete support for IPv6 traffic, `::/0` (i.e. “route _all_ IPv6 traffic through the WireGuard tunnel”) or other IPv6 address ranges can be added to the list of allowed IP addresses. ## Reverse Proxy mitmdump --mode reverse:https://example.com In reverse proxy mode, mitmproxy acts as a normal server. Requests by clients will be forwarded to a preconfigured target server, and responses will be forwarded back to the client:  ### Listen Port With the exception of DNS, reverse proxy servers will listen on port 8080 by default (DNS uses 53). To listen on a different port, append `@portnumber` to the mode. You can also pass `--mode` repeatedly to run multiple reverse proxy servers on different ports. For example, the following command will run a reverse proxy server to example.com on port 80 and 443: mitmdump --mode reverse:https://example.com@80 --mode reverse:https://example.com@443 ### Protocol Specification The examples above have focused on HTTP reverse proxying, but mitmproxy can also reverse proxy other protocols. To adjust the protocol, adjust the scheme in the proxy specification. For example, `--mode reverse:tcp://example.com:80` would establish a raw TCP proxy. | Scheme | client ↔ mitmproxy | mitmproxy ↔ server | | --- | --- | --- | | http:// | HTTP or HTTPS (autodetected) | HTTP | | https:// | HTTP or HTTPS (autodetected) | HTTPS | | dns:// | DNS | DNS | | http3:// | HTTP/3 | HTTP/3 | | quic:// | Raw QUIC | Raw QUIC | | tcp:// | Raw TCP or TCP-over-TLS (autodetected) | Raw TCP | | tls:// | Raw TCP or TCP-over-TLS (autodetected) | Raw TCP-over-TLS | | udp:// | Raw UDP or UDP-over-DTLS (autodetected) | Raw UDP | | dtls:// | Raw UDP or UDP-over-DTLS (autodetected) | Raw UDP-over-DTLS | ### Reverse Proxy Examples * Say you have an internal API running at http://example.local/. You could now set up mitmproxy in reverse proxy mode at http://debug.example.local/ and dynamically point clients to this new API endpoint, which provides them with the same data and you with debug information. Similarly, you could move your real server to a different IP/port and set up mitmproxy in the original place to debug and or redirect all sessions. * Say you’re a web developer working on http://example.com/ (with a development version running on http://localhost:8000/). You can modify your hosts file so that example.com points to 127.0.0.1 and then run mitmproxy in reverse proxy mode on port 80. You can test your app on the example.com domain and get all requests recorded in mitmproxy. * Say you have some toy project that should get TLS support. Simply set up mitmproxy as a reverse proxy on port 443 and you’re done (`mitmdump -p 443 --mode reverse:http://localhost:80/`). Mitmproxy auto-detects TLS traffic and intercepts it dynamically. There are better tools for this specific task, but mitmproxy is very quick and simple way to set up an TLS-speaking server. * Want to know what goes on over (D)TLS (without HTTP)? With mitmproxy’s raw traffic support you can. Use `--mode reverse:tls://example.com:1234` to spawn a TCP instance that connects to `example.com:1234` using TLS, and `--mode reverse:dtls://example.com:1234` to use UDP and DTLS respectively instead. Incoming client connections can either use (D)TLS themselves or raw TCP/UDP. In case you want to inspect raw traffic only for some hosts and HTTP for others, have a look at the tcp\_hosts and udp\_hosts options. * Say you want to capture DNS traffic to Google’s Public DNS server? Then you can spawn a reverse instance with `--mode reverse:dns://8.8.8.8`. In case you want to resolve queries locally (ie. using the resolve capabilities provided and configured by your operating system), use DNS Server mode instead. ### Host Header In reverse proxy mode, mitmproxy automatically rewrites the Host header to match the upstream server. This allows mitmproxy to easily connect to existing endpoints on the open web (e.g. `mitmproxy --mode reverse:https://example.com`). You can disable this behaviour with the `keep_host_header` option. However, keep in mind that absolute URLs within the returned document or HTTP redirects will NOT be rewritten by mitmproxy. This means that if you click on a link for “http://example.com” in the returned web page, you will be taken directly to that URL, bypassing mitmproxy. One possible way to address this is to modify the hosts file of your OS so that “example.com” resolves to your proxy’s IP, and then access the proxy by going directly to example.com. Make sure that your proxy can still resolve the original IP, or specify an IP in mitmproxy. ### Caveat: Interactive Use Reverse Proxy mode is usually not sufficient to create a copy of an interactive website at different URL. The HTML served to the client remains unchanged - as soon as the user clicks on an non-relative URL (or downloads a non-relative image resource), traffic no longer passes through mitmproxy. ## Transparent Proxy Consider using WireGuard and local capture mode instead of transparent mode. They are easier to set up and also support UDP-based protocols (which transparent mode currently does not). _Availability: Linux, macOS_ In transparent mode, traffic is directed into a proxy at the network layer, without any client configuration required. This makes transparent proxying ideal for situations where you can’t change client behaviour: mitmdump --mode transparent In the graphic below, a machine running mitmproxy has been inserted between the router and the internet:  The square brackets signify the source and destination IP addresses. Round brackets mark the next hop on the _Ethernet/data link_ layer. This distinction is important: when the packet arrives at the mitmproxy machine, it must still be addressed to the target server. This means that Network Address Translation should not be applied before the traffic reaches mitmproxy, since this would remove the target information, leaving mitmproxy unable to determine the real destination.  ### Common Configurations There are many ways to configure your network for transparent proxying. We’ll look at two common scenarios: 1. Configuring the client to use a custom gateway/router/“next hop” 2. Implementing custom routing on the router In most cases, the first option is recommended due to its ease of use. #### (a) Custom Gateway One simple way to get traffic to the mitmproxy machine with the destination IP intact, is to simply configure the client with the mitmproxy box as the default gateway.  In this scenario, we would: 1. Configure the proxy machine for transparent mode. You can find instructions in the transparent section. 2. Configure the client to use the proxy machine’s IP as the default gateway. 3. Quick Check: At this point, you should already be able to visit an unencrypted HTTP site over the proxy. 4. Open the magic domain **mitm.it** and install the certificate for your device. Setting the custom gateway on clients can be automated by serving the settings out to clients over DHCP. This lets set up an interception network where all clients are proxied automatically, which can save time and effort. ### Troubleshooting Transparent Mode Incorrect transparent mode configurations are a frequent source of error. If it doesn’t work for you, try the following things: * Open mitmproxy’s event log - do you see clientconnect messages? If not, the packets are not arriving at the proxy. One common cause is the occurrence of ICMP redirects, which means that your machine is telling the client that there’s a faster way to the internet by contacting your router directly (see the transparent section on how to disable them). If in doubt, Wireshark may help you to see whether something arrives at your machine or not. * Make sure you have not explicitly configured an HTTP proxy on the client. This is not needed in transparent mode. * Re-check the instructions in the transparent section. Anything you missed? If you encounter any other pitfalls that should be listed here, please let us know! #### (b) Custom Routing In some cases, you may need more fine-grained control of which traffic reaches the mitmproxy instance, and which doesn’t. You may, for instance, choose only to divert traffic to some hosts into the transparent proxy. There are a huge number of ways to accomplish this, and much will depend on the router or packet filter you’re using. In most cases, the configuration will look like this:  ## TUN Interface _Availability: Linux, macOS_ sudo mitmdump --mode tun In TUN mode, mitmproxy creates a virtual network interface on the system. All traffic routed to this interface will be intercepted by mitmproxy. For example, `curl --interface tun0 http://example.com/` will be transparently intercepted. For most applications, you will need to manually configure your local routing table. You can optionally specify a fixed interface name: sudo mitmdump --mode tun:mitm-tun This mode requires root privileges (or `CAP_NET_ADMIN` on the Python interpreter) to create the tun interface. #### Usage with Containers Mitmproxy’s docker-entrypoint.sh drops all privileges on startup by default. To make TUN mode work in a container on Linux, you can do something like this: docker run --privileged --network host mitmproxy/mitmproxy bash -c "mitmdump --mode tun" ## Upstream Proxy mitmdump --mode upstream:http://example.com:8081 If you want to chain proxies by adding mitmproxy in front of a different proxy appliance, you can use mitmproxy’s upstream mode. In upstream mode, all requests are unconditionally transferred to an upstream proxy of your choice.  mitmproxy supports both explicit HTTP and explicit HTTPS in upstream proxy mode. You could in theory chain multiple mitmproxy instances in a row, but that doesn’t make any sense in practice (i.e. outside of our tests). ## SOCKS Proxy mitmdump --mode socks5 In this mode, mitmproxy acts as a SOCKS5 proxy. This is similar to the regular proxy mode, but using SOCKS5 instead of HTTP for connection establishment with the proxy. ## DNS Server mitmdump --mode dns This mode will listen for incoming DNS queries and use the resolve capabilities of your operating system to return an answer. For A/AAAA queries you can opt to ignore the system’s hosts file using the `dns_use_hosts_file` option. Custom name servers for lookups can be specified using the `dns_name_servers` option. By default port 53 will be used. To specify a different port, say 5353, use `--mode dns@5353`. --- ## Page: https://docs.mitmproxy.org/stable/concepts/certificates/ Edit on GitHub # About Certificates Mitmproxy can decrypt encrypted traffic on the fly, as long as the client trusts mitmproxy’s built-in certificate authority. Usually this means that the mitmproxy CA certificate has to be installed on the client device. ## Quick Setup By far the easiest way to install the mitmproxy CA certificate is to use the built-in certificate installation app. To do this, start mitmproxy and configure your target device with the correct proxy settings. Now start a browser on the device, and visit the magic domain mitm.it. You should see something like this:  Click on the relevant icon, follow the setup instructions for the platform you’re on and you are good to go. ## The mitmproxy certificate authority The first time mitmproxy is run, it creates the keys for a certificate authority (CA) in the config directory (`~/.mitmproxy` by default). This CA is used for on-the-fly generation of dummy certificates for each visited website. Since your browser won’t trust the mitmproxy CA out of the box, you will either need to click through a TLS certificate warning on every domain, or install the CA certificate once so that it is trusted. The following files are created: | Filename | Contents | | --- | --- | | mitmproxy-ca.pem | The certificate **and the private key** in PEM format. | | mitmproxy-ca-cert.pem | The certificate in PEM format. Use this to distribute on most non-Windows platforms. | | mitmproxy-ca-cert.p12 | The certificate in PKCS12 format. For use on Windows. | | mitmproxy-ca-cert.cer | Same file as .pem, but with an extension expected by some Android devices. | For security reasons, the mitmproxy CA is generated uniquely on the first start and is not shared between mitmproxy installations on different devices. This makes sure that other mitmproxy users cannot intercept your traffic. ### Installing the mitmproxy CA certificate manually Sometimes using the quick install app is not an option and you need to install the CA manually. Below is a list of pointers to manual certificate installation documentation for some common platforms. The mitmproxy CA cert is located in `~/.mitmproxy` after it has been generated at the first start of mitmproxy. * curl on the command line: `curl --proxy 127.0.0.1:8080 --cacert ~/.mitmproxy/mitmproxy-ca-cert.pem https://example.com/` * wget on the command line: `wget -e https_proxy=127.0.0.1:8080 --ca-certificate ~/.mitmproxy/mitmproxy-ca-cert.pem https://example.com/` * macOS * macOS (automated): `sudo security add-trusted-cert -d -p ssl -p basic -k /Library/Keychains/System.keychain ~/.mitmproxy/mitmproxy-ca-cert.pem` * Ubuntu/Debian * Fedora * Arch Linux * Mozilla Firefox * Chrome on Linux * iOS On recent iOS versions you also need to enable full trust for the mitmproxy root certificate: 1. Go to Settings > General > About > Certificate Trust Settings. 2. Under “Enable full trust for root certificates”, turn on trust for the mitmproxy certificate. * iOS Simulator 1. Ensure the macOS machine running the emulator is configured to use mitmproxy in its network settings. 2. Open Safari on the emulator and visit `mitm.it` to download the iOS certificate. 3. Navigate to Settings > General > VPN & Device Management to install the certificate. 4. Go to Settings > About > Certificate Trust Settings and enable trust for the installed root certificate. * Java: `sudo keytool -importcert -alias mitmproxy -storepass changeit -keystore $JAVA_HOME/lib/security/cacerts -trustcacerts -file ~/.mitmproxy/mitmproxy-ca-cert.pem` * Android/Android Simulator * Windows * Windows (automated): `certutil -addstore root mitmproxy-ca-cert.cer` ### Upstream Certificate Sniffing When mitmproxy receives a request to establish TLS (in the form of a ClientHello message), it puts the client on hold and first makes a connection to the upstream server to “sniff” the contents of its TLS certificate. The information gained – Common Name, Organization, Subject Alternative Names – is then used to generate a new interception certificate on-the-fly, signed by the mitmproxy CA. Mitmproxy then returns to the client and continues the handshake with the newly-forged certificate. Upstream cert sniffing is on by default, and can optionally be disabled by turning the `upstream_cert` option off. ### Certificate Pinning Some applications employ Certificate Pinning to prevent man-in-the-middle attacks. This means that **mitmproxy’s** certificates will not be accepted by these applications without modifying them. If the contents of these connections are not important, it is recommended to use the ignore\_hosts feature to prevent **mitmproxy** from intercepting traffic to these specific domains. If you want to intercept the pinned connections, you need to patch the application manually. For Android and (jailbroken) iOS devices, various tools exist to accomplish this: * apk-mitm is a CLI application that automatically removes certificate pinning from Android APK files. * objection is a runtime mobile exploration toolkit powered by Frida, which supports certificate pinning bypasses on iOS and Android. * ssl-kill-switch2 is a blackbox tool to disable certificate pinning within iOS and macOS applications. * android-unpinner modifies Android APKs to inject Frida and HTTP Toolkit’s unpinning scripts. _Please propose other useful tools using the “Edit on GitHub” button on the top right of this page._ ## Using a custom server certificate You can use your own (leaf) certificate by passing the `--certs [domain=]path_to_certificate` option to mitmproxy. Mitmproxy then uses the provided certificate for interception of the specified domain instead of generating a certificate signed by its own CA. The certificate file is expected to be in the PEM format. You can include intermediary certificates right below your leaf certificate, so that your PEM file roughly looks like this: -----BEGIN PRIVATE KEY----- <private key> -----END PRIVATE KEY----- -----BEGIN CERTIFICATE----- <cert> -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- <intermediary cert (optional)> -----END CERTIFICATE----- For example, you can generate a certificate in this format using these instructions: openssl genrsa -out cert.key 2048 # (Specify the mitm domain as Common Name, e.g. \*.google.com) openssl req -new -x509 -key cert.key -out cert.crt cat cert.key cert.crt > cert.pem Now, you can run mitmproxy with the generated certificate: **For all domain names** mitmproxy --certs *=cert.pem **For specific domain names** mitmproxy --certs *.example.com=cert.pem **Note:** `*.example.com` is for all the subdomains. You can also use `www.example.com` for a particular subdomain. ## Using a custom certificate authority By default, mitmproxy will use `~/.mitmproxy/mitmproxy-ca.pem` as the certificate authority to generate certificates for all domains for which no custom certificate is provided (see above). You can use your own certificate authority by passing the `--set confdir=DIRECTORY` option to mitmproxy. Mitmproxy will then look for `mitmproxy-ca.pem` in the specified directory. If no such file exists, it will be generated automatically. The `mitmproxy-ca.pem` certificate file has to look roughly like this: -----BEGIN PRIVATE KEY----- <private key> -----END PRIVATE KEY----- -----BEGIN CERTIFICATE----- <cert> -----END CERTIFICATE----- When looking at the certificate with `openssl x509 -noout -text -in ~/.mitmproxy/mitmproxy-ca.pem` it should have at least the following X509v3 extensions so mitmproxy can use it to generate certificates: X509v3 extensions: X509v3 Key Usage: critical Certificate Sign X509v3 Basic Constraints: critical CA:TRUE For example, when using OpenSSL, you can create a CA authority as follows: openssl req -x509 -new -nodes -key ca.key -sha256 -out ca.crt -addext keyUsage=critical,keyCertSign cat ca.key ca.crt > mitmproxy-ca.pem ## Mutual TLS (mTLS) and client certificates TLS is typically used in a way where the client verifies the server’s identity using the server’s certificate during the handshake, but the server does not verify the client’s identity using the TLS protocol. Instead, the client transmits cookies or other access tokens over the established secure channel to authenticate itself. Mutual TLS (mTLS) is a mode where the server verifies the client’s identity not using cookies or access tokens, but using a certificate presented by the client during the TLS handshake. With mTLS, both client and server use a certificate to authenticate each other. If a server wants to verify the clients identity using mTLS, it sends an additional `CertificateRequest` message to the client during the handshake. The client then provides its certificate and proves ownership of the private key with a matching signature. This part works just like server authentication, only the other way around. ### mTLS between mitmproxy and upstream server You can use a client certificate by passing the `--set client_certs=DIRECTORY|FILE` option to mitmproxy. Using a directory allows certs to be selected based on hostname, while using a filename allows a single specific certificate to be used for all TLS connections. Certificate files must be in the PEM format and should contain both the unencrypted private key and the certificate. You can specify a directory to `--set client_certs=DIRECTORY`, in which case the matching certificate is looked up by filename. So, if you visit example.org, mitmproxy looks for a file named `example.org.pem` in the specified directory and uses this as the client cert. ### mTLS between client and mitmproxy By default, mitmproxy does not send the `CertificateRequest` TLS handshake message to connecting clients. This is because it trips up some clients that do not expect a certificate request (most famously old Android versions). However, there are other clients – in particular in the MQTT / IoT environment – that do expect a certificate request and will otherwise fail the TLS handshake. To instruct mitmproxy to request a client certificate from the connecting client, you can pass the `--set request_client_cert=True` option. This will generate a `CertificateRequest` TLS handshake message and (if successful) establish an mTLS connection. This option only requests a certificate from the client, it does not validate the presented identity in any way. For the purposes of testing and developing client and server software, this is typically not an issue. If you operate mitmproxy in an environment where untrusted clients might connect, you need to safeguard against them. The `request_client_cert` option is typically paired with `client_certs` like so: mitmproxy --set request_client_cert=True --set client_certs=client-cert.pem --- ## Page: https://docs.mitmproxy.org/stable/concepts/filters/ Edit on GitHub # Filter expressions Many commands in the mitmproxy tool make use of filter expressions. Filter expressions consist of the following operators: <table><tbody><tr><th>~a</th><td>Match asset in response: CSS, JavaScript, images, fonts.</td></tr><tr><th>~all</th><td>Match all flows</td></tr><tr><th>~b regex</th><td>Body</td></tr><tr><th>~bq regex</th><td>Request body</td></tr><tr><th>~bs regex</th><td>Response body</td></tr><tr><th>~c int</th><td>HTTP response code</td></tr><tr><th>~comment regex</th><td>Flow comment</td></tr><tr><th>~d regex</th><td>Domain</td></tr><tr><th>~dns</th><td>Match DNS flows</td></tr><tr><th>~dst regex</th><td>Match destination address</td></tr><tr><th>~e</th><td>Match error</td></tr><tr><th>~h regex</th><td>Header</td></tr><tr><th>~hq regex</th><td>Request header</td></tr><tr><th>~hs regex</th><td>Response header</td></tr><tr><th>~http</th><td>Match HTTP flows</td></tr><tr><th>~m regex</th><td>Method</td></tr><tr><th>~marked</th><td>Match marked flows</td></tr><tr><th>~marker regex</th><td>Match marked flows with specified marker</td></tr><tr><th>~meta regex</th><td>Flow metadata</td></tr><tr><th>~q</th><td>Match request with no response</td></tr><tr><th>~replay</th><td>Match replayed flows</td></tr><tr><th>~replayq</th><td>Match replayed client request</td></tr><tr><th>~replays</th><td>Match replayed server response</td></tr><tr><th>~s</th><td>Match response</td></tr><tr><th>~src regex</th><td>Match source address</td></tr><tr><th>~t regex</th><td>Content-type header</td></tr><tr><th>~tcp</th><td>Match TCP flows</td></tr><tr><th>~tq regex</th><td>Request Content-Type header</td></tr><tr><th>~ts regex</th><td>Response Content-Type header</td></tr><tr><th>~u regex</th><td>URL</td></tr><tr><th>~udp</th><td>Match UDP flows</td></tr><tr><th>~websocket</th><td>Match WebSocket flows</td></tr><tr><th>!</th><td>unary not</td></tr><tr><th>&</th><td>and</td></tr><tr><th>|</th><td>or</td></tr><tr><th>(...)</th><td>grouping</td></tr></tbody></table> * Regexes are Python-style. * Regexes can be specified as quoted strings. * Regexes are case-insensitive by default.1 * Header matching (~h, ~hq, ~hs) is against a string of the form “name: value”. * Strings with no operators are matched against the request URL. * The default binary operator is &. ## View flow selectors In interactive contexts, mitmproxy has a set of convenient flow selectors that operate on the current view: <table><tbody><tr><th>@all</th><td>All flows</td></tr><tr><th>@focus</th><td>The currently focused flow</td></tr><tr><th>@shown</th><td>All flows currently shown</td></tr><tr><th>@hidden</th><td>All flows currently hidden</td></tr><tr><th>@marked</th><td>All marked flows</td></tr><tr><th>@unmarked</th><td>All unmarked flows</td></tr></tbody></table> These are frequently used in commands and key bindings. ## Examples URL containing “google.com”: google\.com Requests whose body contains the string “test”: ~q ~b test Anything but requests with a text/html content type: !(~q & ~t "text/html") Replace entire GET string in a request (quotes required to make it work): ":~q ~m GET:.*:/replacement.html" * * * 1. This can be disabled by setting `MITMPROXY_CASE_SENSITIVE_FILTERS=1` as an environment variable. ↩︎ --- ## Page: https://docs.mitmproxy.org/stable/concepts/options/ Edit on GitHub # Options The mitmproxy tools share a common YAML configuration file located at `~/.mitmproxy/config.yaml`. This file controls **options** - typed values that determine the behaviour of mitmproxy. The options mechanism is very comprehensive - in fact, options control all of mitmproxy’s runtime behaviour. Most command-line flags are simply aliases for underlying options, and interactive settings changes made in **mitmproxy** and **mitmweb** just change values in our runtime options store. This means that almost any facet of mitmproxy’s behaviour can be controlled through options. The canonical reference for options is the `--options` flag, which is exposed by each of the mitmproxy tools. Passing this flag will dump an annotated YAML configuration to console, which includes all options and their default values. The options mechanism is extensible - third-party addons can define options that are treated exactly like mitmproxy’s own. This means that addons can also be configured through the central configuration file, and their options will appear in the options editors in interactive tools. ## Tools Both **mitmproxy** and **mitmweb** have built-in editors that let you view and manipulate the complete configuration state of mitmproxy. Values you change interactively have immediate effect in the running instance, and can be made persistent by saving the settings out to a YAML configuration file (please see the specific tool’s interactive help for details on how to do this). For all tools, options can be set directly by name using the `--set` command-line option. Please see the command-line help (`--help`) for usage. Example: mitmproxy --set anticomp=true mitmweb --set ignore_hosts=example.com --set ignore_hosts=example.org ## Available Options This list might not reflect what is actually available in your current mitmproxy environment. For an up-to-date list please use the `--options` flag for each of the mitmproxy tools. | Name | Type | Description | | --- | --- | --- | | add\_upstream\_certs\_to\_client\_chain mitmproxy mitmdump mitmweb | bool | Add all certificates of the upstream server to the certificate chain that will be served to the proxy client, as extras. Default: False | | allow\_hosts mitmproxy mitmdump mitmweb | sequence of str | Opposite of --ignore-hosts. Default: \[\] | | anticache mitmproxy mitmdump mitmweb | bool | Strip out request headers that might cause the server to return 304-not-modified. Default: False | | anticomp mitmproxy mitmdump mitmweb | bool | Try to convince servers to send us un-compressed data. Default: False | | block\_global mitmproxy mitmdump mitmweb | bool | Block connections from public IP addresses. Default: True | | block\_list mitmproxy mitmdump mitmweb | sequence of str | Block matching requests and return an empty response with the specified HTTP status. Option syntax is "/flow-filter/status-code", where flow-filter describes which requests this rule should be applied to and status-code is the HTTP status code to return for blocked requests. The separator ("/" in the example) can be any character. Setting a non-standard status code of 444 will close the connection without sending a response. Default: \[\] | | block\_private mitmproxy mitmdump mitmweb | bool | Block connections from local (private) IP addresses. This option does not affect loopback addresses (connections from the local machine), which are always permitted. Default: False | | body\_size\_limit mitmproxy mitmdump mitmweb | optional str | Byte size limit of HTTP request and response bodies. Understands k/m/g suffixes, i.e. 3m for 3 megabytes. Default: None | | cert\_passphrase mitmproxy mitmdump mitmweb | optional str | Passphrase for decrypting the private key provided in the --cert option. Note that passing cert\_passphrase on the command line makes your passphrase visible in your system's process list. Specify it in config.yaml to avoid this. Default: None | | certs mitmproxy mitmdump mitmweb | sequence of str | SSL certificates of the form "\[domain=\]path". The domain may include a wildcard, and is equal to "\*" if not specified. The file at path is a certificate in PEM format. If a private key is included in the PEM, it is used, else the default key in the conf dir is used. The PEM file should contain the full certificate chain, with the leaf certificate as the first entry. Default: \[\] | | ciphers\_client mitmproxy mitmdump mitmweb | optional str | Set supported ciphers for client <-> mitmproxy connections using OpenSSL syntax. Default: None | | ciphers\_server mitmproxy mitmdump mitmweb | optional str | Set supported ciphers for mitmproxy <-> server connections using OpenSSL syntax. Default: None | | client\_certs mitmproxy mitmdump mitmweb | optional str | Client certificate file or directory. Default: None | | client\_replay mitmproxy mitmdump mitmweb | sequence of str | Replay client requests from a saved file. Default: \[\] | | client\_replay\_concurrency mitmproxy mitmdump mitmweb | int | Concurrency limit on in-flight client replay requests. Currently the only valid values are 1 and -1 (no limit). Default: 1 | | command\_history mitmproxy mitmdump mitmweb | bool | Persist command history between mitmproxy invocations. Default: True | | confdir mitmproxy mitmdump mitmweb | str | Location of the default mitmproxy configuration files. Default: ~/.mitmproxy | | connect\_addr mitmproxy mitmdump mitmweb | optional str | Set the local IP address that mitmproxy should use when connecting to upstream servers. Default: None | | connection\_strategy mitmproxy mitmdump mitmweb | str | Determine when server connections should be established. When set to lazy, mitmproxy tries to defer establishing an upstream connection as long as possible. This makes it possible to use server replay while being offline. When set to eager, mitmproxy can detect protocols with server-side greetings, as well as accurately mirror TLS ALPN negotiation. Default: eager Choices: eager, lazy | | console\_default\_contentview mitmproxy | str | The default content view mode. Default: auto Choices: auto, dns, graphql, grpc, hex dump, hex stream, http/3 frames, image, javascript, json, mqtt, msgpack, multipart form, protobuf, query, raw, socket.io, url-encoded, viewcss, wbxml, xml/html | | console\_eventlog\_verbosity mitmproxy | str | EventLog verbosity. Default: info Choices: error, warn, info, alert, debug | | console\_flowlist\_layout mitmproxy | str | Set the flowlist layout Default: default Choices: default, list, table | | console\_focus\_follow mitmproxy mitmweb | bool | Focus follows new flows. Default: False | | console\_layout mitmproxy | str | Console layout. Default: single Choices: horizontal, single, vertical | | console\_layout\_headers mitmproxy | bool | Show layout component headers Default: True | | console\_mouse mitmproxy | bool | Console mouse interaction. Default: True | | console\_palette mitmproxy | str | Color palette. Default: solarized\_dark Choices: dark, light, lowdark, lowlight, solarized\_dark, solarized\_light | | console\_palette\_transparent mitmproxy | bool | Set transparent background for palette. Default: True | | console\_strip\_trailing\_newlines mitmproxy | bool | Strip trailing newlines from edited request/response bodies. Default: False | | content\_view\_lines\_cutoff mitmproxy mitmdump mitmweb | int | Flow content view lines limit. Limit is enabled by default to speedup flows browsing. Default: 512 | | dns\_name\_servers mitmproxy mitmdump mitmweb | sequence of str | Name servers to use for lookups. Default: operating system's name servers Default: \[\] | | dns\_use\_hosts\_file mitmproxy mitmdump mitmweb | bool | Use the hosts file for DNS lookups in regular DNS mode/wireguard mode. Default: True | | dumper\_default\_contentview mitmdump | str | The default content view mode. Default: auto Choices: auto, dns, graphql, grpc, hex dump, hex stream, http/3 frames, image, javascript, json, mqtt, msgpack, multipart form, protobuf, query, raw, socket.io, url-encoded, viewcss, wbxml, xml/html | | dumper\_filter mitmdump | optional str | Limit which flows are dumped. Default: None | | export\_preserve\_original\_ip mitmproxy mitmdump mitmweb | bool | When exporting a request as an external command, make an effort to connect to the same IP as in the original request. This helps with reproducibility in cases where the behaviour depends on the particular host we are connecting to. Currently this only affects curl exports. Default: False | | flow\_detail mitmdump | int | The display detail level for flows in mitmdump: 0 (quiet) to 4 (very verbose). 0: no output 1: shortened request URL with response status code 2: full request URL with response status code and HTTP headers 3: 2 + truncated response content, content of WebSocket and TCP messages (content\_view\_lines\_cutoff: 512) 4: 3 + nothing is truncated Default: 1 | | hardump mitmproxy mitmdump mitmweb | str | Save a HAR file with all flows on exit. You may select particular flows by setting save\_stream\_filter. For mitmdump, enabling this option will mean that flows are kept in memory. Default: | | http2 mitmproxy mitmdump mitmweb | bool | Enable/disable HTTP/2 support. HTTP/2 support is enabled by default. Default: True | | http2\_ping\_keepalive mitmproxy mitmdump mitmweb | int | Send a PING frame if an HTTP/2 connection is idle for more than the specified number of seconds to prevent the remote site from closing it. Set to 0 to disable this feature. Default: 58 | | http3 mitmproxy mitmdump mitmweb | bool | Enable/disable support for QUIC and HTTP/3. Enabled by default. Default: True | | http\_connect\_send\_host\_header mitmproxy mitmdump mitmweb | bool | Include host header with CONNECT requests. Enabled by default. Default: True | | ignore\_hosts mitmproxy mitmdump mitmweb | sequence of str | Ignore host and forward all traffic without processing it. In transparent mode, it is recommended to use an IP address (range), not the hostname. In regular mode, only SSL traffic is ignored and the hostname should be used. The supplied value is interpreted as a regular expression and matched on the ip or the hostname. Default: \[\] | | intercept mitmproxy mitmweb | optional str | Intercept filter expression. Default: None | | intercept\_active mitmproxy mitmweb | bool | Intercept toggle Default: False | | keep\_alt\_svc\_header mitmproxy mitmdump mitmweb | bool | Reverse Proxy: Keep Alt-Svc headers as-is, even if they do not point to mitmproxy. Enabling this option may cause clients to bypass the proxy. Default: False | | keep\_host\_header mitmproxy mitmdump mitmweb | bool | Reverse Proxy: Keep the original host header instead of rewriting it to the reverse proxy target. Default: False | | keepserving mitmdump | bool | Continue serving after client playback, server playback or file read. This option is ignored by interactive tools, which always keep serving. Default: False | | key\_size mitmproxy mitmdump mitmweb | int | TLS key size for certificates and CA. Default: 2048 | | listen\_host mitmproxy mitmdump mitmweb | str | Address to bind proxy server(s) to (may be overridden for individual modes, see \`mode\`). Default: | | listen\_port mitmproxy mitmdump mitmweb | optional int | Port to bind proxy server(s) to (may be overridden for individual modes, see \`mode\`). By default, the port is mode-specific. The default regular HTTP proxy spawns on port 8080. Default: None | | map\_local mitmproxy mitmdump mitmweb | sequence of str | Map remote resources to a local file using a pattern of the form "\[/flow-filter\]/url-regex/file-or-directory-path", where the separator can be any character. Default: \[\] | | map\_remote mitmproxy mitmdump mitmweb | sequence of str | Map remote resources to another remote URL using a pattern of the form "\[/flow-filter\]/url-regex/replacement", where the separator can be any character. Default: \[\] | | mode mitmproxy mitmdump mitmweb | sequence of str | The proxy server type(s) to spawn. Can be passed multiple times. Mitmproxy supports "regular" (HTTP), "transparent", "socks5", "reverse:SPEC", "upstream:SPEC", and "wireguard\[:PATH\]" proxy servers. For reverse and upstream proxy modes, SPEC is host specification in the form of "http\[s\]://host\[:port\]". For WireGuard mode, PATH may point to a file containing key material. If no such file exists, it will be created on startup. You may append \`@listen\_port\` or \`@listen\_host:listen\_port\` to override \`listen\_host\` or \`listen\_port\` for a specific proxy mode. Features such as client playback will use the first mode to determine which upstream server to use. Default: \['regular'\] | | modify\_body mitmproxy mitmdump mitmweb | sequence of str | Replacement pattern of the form "\[/flow-filter\]/regex/\[@\]replacement", where the separator can be any character. The @ allows to provide a file path that is used to read the replacement string. Default: \[\] | | modify\_headers mitmproxy mitmdump mitmweb | sequence of str | Header modify pattern of the form "\[/flow-filter\]/header-name/\[@\]header-value", where the separator can be any character. The @ allows to provide a file path that is used to read the header value string. An empty header-value removes existing header-name headers. Default: \[\] | | normalize\_outbound\_headers mitmproxy mitmdump mitmweb | bool | Normalize outgoing HTTP/2 header names, but emit a warning when doing so. HTTP/2 does not allow uppercase header names. This option makes sure that HTTP/2 headers set in custom scripts are lowercased before they are sent. Default: True | | onboarding mitmproxy mitmdump mitmweb | bool | Toggle the mitmproxy onboarding app. Default: True | | onboarding\_host mitmproxy mitmdump mitmweb | str | Onboarding app domain. For transparent mode, use an IP when a DNS entry for the app domain is not present. Default: mitm.it | | protobuf\_definitions mitmproxy mitmdump mitmweb | optional str | Path to a .proto file that's used to resolve Protobuf field names when pretty-printing. Default: None | | proxy\_debug mitmproxy mitmdump mitmweb | bool | Enable debug logs in the proxy core. Default: False | | proxyauth mitmproxy mitmdump mitmweb | optional str | Require proxy authentication. Format: "username:pass", "any" to accept any user/pass combination, "@path" to use an Apache htpasswd file, or "ldap\[s\]:url\_server\_ldap\[:port\]:dn\_auth:password:dn\_subtree\[?search\_filter\_key=...\]" for LDAP authentication. Default: None | | rawtcp mitmproxy mitmdump mitmweb | bool | Enable/disable raw TCP connections. TCP connections are enabled by default. Default: True | | readfile\_filter mitmproxy mitmdump mitmweb | optional str | Read only matching flows. Default: None | | request\_client\_cert mitmproxy mitmdump mitmweb | bool | Requests a client certificate (TLS message 'CertificateRequest') to establish a mutual TLS connection between client and mitmproxy (combined with 'client\_certs' option for mitmproxy and upstream). Default: False | | rfile mitmproxy mitmdump mitmweb | optional str | Read flows from file. Default: None | | save\_stream\_file mitmproxy mitmdump mitmweb | optional str | Stream flows to file as they arrive. Prefix path with + to append. The full path can use python strftime() formating, missing directories are created as needed. A new file is opened every time the formatted string changes. Default: None | | save\_stream\_filter mitmproxy mitmdump mitmweb | optional str | Filter which flows are written to file. Default: None | | scripts mitmproxy mitmdump mitmweb | sequence of str | Execute a script. Default: \[\] | | server mitmproxy mitmdump mitmweb | bool | Start a proxy server. Enabled by default. Default: True | | server\_replay mitmproxy mitmdump mitmweb | sequence of str | Replay server responses from a saved file. Default: \[\] | | server\_replay\_extra mitmproxy mitmdump mitmweb | str | Behaviour for extra requests during replay for which no replayable response was found. Setting a numeric string value will return an empty HTTP response with the respective status code. Default: forward Choices: forward, kill, 204, 400, 404, 500 | | server\_replay\_ignore\_content mitmproxy mitmdump mitmweb | bool | Ignore request content while searching for a saved flow to replay. Default: False | | server\_replay\_ignore\_host mitmproxy mitmdump mitmweb | bool | Ignore request destination host while searching for a saved flow to replay. Default: False | | server\_replay\_ignore\_params mitmproxy mitmdump mitmweb | sequence of str | Request parameters to be ignored while searching for a saved flow to replay. Default: \[\] | | server\_replay\_ignore\_payload\_params mitmproxy mitmdump mitmweb | sequence of str | Request payload parameters (application/x-www-form-urlencoded or multipart/form-data) to be ignored while searching for a saved flow to replay. Default: \[\] | | server\_replay\_ignore\_port mitmproxy mitmdump mitmweb | bool | Ignore request destination port while searching for a saved flow to replay. Default: False | | server\_replay\_kill\_extra mitmproxy mitmdump mitmweb | bool | Kill extra requests during replay (for which no replayable response was found).\[Deprecated, prefer to use server\_replay\_extra='kill'\] Default: False | | server\_replay\_nopop mitmproxy mitmdump mitmweb | bool | Deprecated alias for \`server\_replay\_reuse\`. Default: False | | server\_replay\_refresh mitmproxy mitmdump mitmweb | bool | Refresh server replay responses by adjusting date, expires and last-modified headers, as well as adjusting cookie expiration. Default: True | | server\_replay\_reuse mitmproxy mitmdump mitmweb | bool | Don't remove flows from server replay state after use. This makes it possible to replay same response multiple times. Default: False | | server\_replay\_use\_headers mitmproxy mitmdump mitmweb | sequence of str | Request headers that need to match while searching for a saved flow to replay. Default: \[\] | | show\_ignored\_hosts mitmproxy mitmdump mitmweb | bool | Record ignored flows in the UI even if we do not perform TLS interception. This option will keep ignored flows' contents in memory, which can greatly increase memory usage. A future release will fix this issue, record ignored flows by default, and remove this option. Default: False | | showhost mitmproxy mitmdump mitmweb | bool | Use the Host header to construct URLs for display. This option is disabled by default because malicious apps may send misleading host headers to evade your analysis. If this is not a concern, enable this options for better flow display. Default: False | | ssl\_insecure mitmproxy mitmdump mitmweb | bool | Do not verify upstream server SSL/TLS certificates. If this option is enabled, certificate validation is skipped and mitmproxy itself will be vulnerable to TLS interception. Default: False | | ssl\_verify\_upstream\_trusted\_ca mitmproxy mitmdump mitmweb | optional str | Path to a PEM formatted trusted CA certificate. Default: None | | ssl\_verify\_upstream\_trusted\_confdir mitmproxy mitmdump mitmweb | optional str | Path to a directory of trusted CA certificates for upstream server verification prepared using the c\_rehash tool. Default: None | | stickyauth mitmproxy mitmdump mitmweb | optional str | Set sticky auth filter. Matched against requests. Default: None | | stickycookie mitmproxy mitmdump mitmweb | optional str | Set sticky cookie filter. Matched against requests. Default: None | | store\_streamed\_bodies mitmproxy mitmdump mitmweb | bool | Store HTTP request and response bodies when streamed (see \`stream\_large\_bodies\`). This increases memory consumption, but makes it possible to inspect streamed bodies. Default: False | | stream\_large\_bodies mitmproxy mitmdump mitmweb | optional str | Stream data to the client if request or response body exceeds the given threshold. If streamed, the body will not be stored in any way, and such responses cannot be modified. Understands k/m/g suffixes, i.e. 3m for 3 megabytes. To store streamed bodies, see \`store\_streamed\_bodies\`. Default: None | | strip\_ech mitmproxy mitmdump mitmweb | bool | Strip Encrypted ClientHello (ECH) data from DNS HTTPS records so that mitmproxy can generate matching certificates. Default: True | | tcp\_hosts mitmproxy mitmdump mitmweb | sequence of str | Generic TCP SSL proxy mode for all hosts that match the pattern. Similar to --ignore-hosts, but SSL connections are intercepted. The communication contents are printed to the log in verbose mode. Default: \[\] | | termlog\_verbosity mitmdump mitmweb | str | Log verbosity. Default: info Choices: error, warn, info, alert, debug | | tls\_ecdh\_curve\_client mitmproxy mitmdump mitmweb | optional str | Use a specific elliptic curve for ECDHE key exchange on client connections. OpenSSL syntax, for example "prime256v1" (see \`openssl ecparam -list\_curves\`). Default: None | | tls\_ecdh\_curve\_server mitmproxy mitmdump mitmweb | optional str | Use a specific elliptic curve for ECDHE key exchange on server connections. OpenSSL syntax, for example "prime256v1" (see \`openssl ecparam -list\_curves\`). Default: None | | tls\_version\_client\_max mitmproxy mitmdump mitmweb | str | Set the maximum TLS version for client connections. Default: UNBOUNDED Choices: UNBOUNDED, SSL3, TLS1, TLS1\_1, TLS1\_2, TLS1\_3 | | tls\_version\_client\_min mitmproxy mitmdump mitmweb | str | Set the minimum TLS version for client connections. UNBOUNDED, SSL3, TLS1 and TLS1\_1 are insecure. Default: TLS1\_2 Choices: UNBOUNDED, SSL3, TLS1, TLS1\_1, TLS1\_2, TLS1\_3 | | tls\_version\_server\_max mitmproxy mitmdump mitmweb | str | Set the maximum TLS version for server connections. Default: UNBOUNDED Choices: UNBOUNDED, SSL3, TLS1, TLS1\_1, TLS1\_2, TLS1\_3 | | tls\_version\_server\_min mitmproxy mitmdump mitmweb | str | Set the minimum TLS version for server connections. UNBOUNDED, SSL3, TLS1 and TLS1\_1 are insecure. Default: TLS1\_2 Choices: UNBOUNDED, SSL3, TLS1, TLS1\_1, TLS1\_2, TLS1\_3 | | udp\_hosts mitmproxy mitmdump mitmweb | sequence of str | Generic UDP SSL proxy mode for all hosts that match the pattern. Similar to --ignore-hosts, but SSL connections are intercepted. The communication contents are printed to the log in verbose mode. Default: \[\] | | upstream\_auth mitmproxy mitmdump mitmweb | optional str | Add HTTP Basic authentication to upstream proxy and reverse proxy requests. Format: username:password. Default: None | | upstream\_cert mitmproxy mitmdump mitmweb | bool | Connect to upstream server to look up certificate details. Default: True | | validate\_inbound\_headers mitmproxy mitmdump mitmweb | bool | Make sure that incoming HTTP requests are not malformed. Disabling this option makes mitmproxy vulnerable to HTTP smuggling attacks. Default: True | | view\_filter mitmproxy mitmweb | optional str | Limit the view to matching flows. Default: None | | view\_order mitmproxy mitmweb | str | Flow sort order. Default: time Choices: time, method, url, size | | view\_order\_reversed mitmproxy mitmweb | bool | Reverse the sorting order. Default: False | | web\_columns mitmweb | sequence of str | Columns to show in the flow list. Can be one of the following: icon, index, method, version, path, quickactions, size, status, time, timestamp, tls, comment Default: \['tls', 'icon', 'path', 'method', 'status', 'size', 'time'\] | | web\_debug mitmweb | bool | Enable mitmweb debugging. Default: False | | web\_host mitmweb | str | Web UI host. Default: 127.0.0.1 | | web\_open\_browser mitmweb | bool | Start a browser. Default: True | | web\_password mitmweb | str | Password to protect the mitmweb user interface. Values starting with \`$\` are interpreted as an argon2 hash, everything else is considered a plaintext password. If no password is provided, a random token is generated on startup.For automated calls, you can pass the password as token query parameteror as \`Authentication: Bearer ...\` header. Default: | | web\_port mitmweb | int | Web UI port. Default: 8081 | | web\_static\_viewer mitmweb | optional str | The path to output a static viewer. Default: | | websocket mitmproxy mitmdump mitmweb | bool | Enable/disable WebSocket support. WebSocket support is enabled by default. Default: True | --- ## Page: https://docs.mitmproxy.org/stable/concepts/commands/ Edit on GitHub # Commands Commands are the mechanism that allows users to actively interact with addons. Perhaps the most prominent example of this is the mitmproxy console user interface - every interaction in this tool consists of commands bound to keys. Commands also form a flexible and very powerful way to interact with mitmproxy from the command prompt. In mitmproxy console you can enter the command prompt with the `:` key. The prompt has intelligent tab completion for command names and many of the built-in argument types - give it a try. The canonical reference for commands is the `--commands` flag, which is exposed by each of the mitmproxy tools. Passing this flag will dump an annotated list of all registered commands, their arguments and their return values to screen. In mitmproxy console you can also view a palette of all commands in the command browser (by default accessible with the `C` key binding). # Working with Flows Many of mitmproxy’s commands take flows as arguments. For instance, the signature for the client replay commands looks like this: replay.client [flow] That means that it expects a sequence of one or more flows. This is where flow specifications come in - mitmproxy will intelligently expand a flexible flow selection language to a list of flows when invoking commands. Fire up mitmproxy console, and intercept some traffic so we have flows to work with. Now type the following command: :replay.client @focus Make sure you try using tab completion for the command name and the flow specification. The `@focus` specifiers expands to the currently focused flow, so you should see this flow replay. However, replay can take any number of flows. Try the following command: :replay.client @all Now you should see all flows replay one by one. We have the full power of the mitmproxy filter language at our disposal here, so we could also, for example, just replay flows for a specific domain: :replay.client "~d google.com" # Custom Key Bindings Mitmproxy’s key bindings can be customized to your needs in the `~/.mitmproxy/keys.yaml` file. This file consists of a sequence of maps, with the following keys: * `key` (**mandatory**): The key to bind. * `cmd` (**mandatory**): The command to execute when the key is pressed. * `context`: A list of contexts in which the key should be bound. By default this is **global** (i.e. the key is bound everywhere). Valid contexts are `chooser`, `commands`, `dataviewer`, `eventlog`, `flowlist`, `flowview`, `global`, `grideditor`, `help`, `keybindings`, `options`. * `help`: A help string for the binding which will be shown in the key binding browser. #### Example - # Simple global binding key: ctrl a cmd: replay.client @marked - # Bind key only in the flowlist # Note that 1 is quoted, or YAML interprets it as a digit key: "1" ctx: ["flowlist"] cmd: console.nav.down help: Go to next flow examples/keys.yaml --- ## Page: https://docs.mitmproxy.org/stable/concepts/protocols/ Edit on GitHub # Protocols mitmproxy not only supports HTTP, but also other important web protocols. This page lists details and known limitations of the respective protocol implementations. Most protocols can be disabled by toggling the respective option. ## HTTP/1 HTTP/1.0 and HTTP/1.1 support in mitmproxy is based on our custom HTTP stack based on h11, which is particularly robust to HTTP syntax errors. Protocol violations are often deliberately forwarded or inserted at the proxy. ##### Known Limitations * Trailers: mitmproxy currently does not support trailers with HTTP/1.x, but we are happy to accept contributions. ## HTTP/2 HTTP/2 support in mitmproxy is based on hyper-h2. In case the upstream server does not speak HTTP/2, mitmproxy seamlessly translates messages to HTTP/1. ##### Known Limitations * _Priority Information_: mitmproxy currently ignores HTTP/2 PRIORITY frames. This does not affect the transmitted contents, but potentially affects the order in which messages are sent. * _Push Promises_: mitmproxy currently does not advertise support for HTTP/2 Push Promises. * _Cleartext HTTP/2_: mitmproxy currently does not support unencrypted HTTP/2 (h2c). ## HTTP/3 HTTP/3 support in mitmproxy is based on aioquic. Mitmproxy’s HTTP/3 functionality is available in reverse proxy, local and WireGuard mode. ##### Known Limitations * _Replay_: Client Replay is currently broken. * _Supported Versions_: mitmproxy currently only supports QUIC Version 1. Version 2 (RFC 9369) is not supported yet. * _Implementation Compatibility_: mitmproxy’s HTTP/3 support has only been extensively tested with cURL. Other implementations are likely to exhibit bugs. ## WebSocket WebSocket support in mitmproxy is based on wsproto project, including support for message compression. ##### Known Limitations * _Replay_: Client or server replay is not possible yet. * _Ping_: mitmproxy will forward PING and PONG frames, but not store them. The payload is only logged to the event log. * _Unknown Extensions_: Unknown WebSocket extensions will cause a warning message to be logged, but are otherwise passed through as-is. This may lead to noncompliant behavior. ## DNS DNS support in mitmproxy is based on a custom DNS implementation. ##### Known Limitations * _Replay_: Client or server replay is not possible yet. * We have not started any work on DoT/DoH/DoQ (DNS-over-TLS/HTTPS/QUIC) yet. Contributions are welcome. ## Generic TCP/TLS Proxy Mitmproxy can also act as a generic TCP proxy. In this mode, mitmproxy will still detect the presence of TLS at the beginning of a connection and perform a man-in-the-middle attack if necessary, but otherwise forward messages unmodified. Users can explicitly opt into generic TCP proxying by setting the `tcp_hosts` option. ##### Known Limitations * _Replay_: Client or server replay is not possible yet. * _Opportunistic TLS_: mitmproxy will not detect when a plaintext protocol upgrades to TLS (STARTTLS). ## Generic UDP/DTLS Proxy Mitmproxy can also act as a generic UDP proxy. In this mode, mitmproxy will still detect the presence of DTLS at the beginning of a connection and perform a man-in-the-middle attack if necessary, but otherwise forward messages unmodified. Users can explicitly opt into generic UDP proxying by setting the `udp_hosts` option. ##### Known Limitations * _Replay_: Client or server replay is not possible yet.