HTTPS Decryption (Man-in-the-Middle Attack, MitM)

Chute may decrypt HTTPS traffic by MitM. Please see Wikipedia article for more information. On iPhone, Apple TV and Android this is a licensed feature and the engine enforces it: without a license nothing is decrypted, whatever the configuration says. See License and Activation.

The certificate generator can help you generate a new CA certificate for debugging and make the certificate trusted by the system. It's available in Chute Mac and Chute iOS Chute Editor. This certificate is generated locally and only saved in your profile file and the system Keychain. The key of the new certificate is generated randomly using OpenSSL. Chute Android has no generator: import an existing PKCS#12 under MitM → Configure CA in the editor, and Install CA hands its CA certificate to Android's certificate installer — see Installing and trusting the CA certificate.

You can also use an existed CA certificate. Export the certificate to PKCS#12 format (.p12) with passphrase. Please note that the passphrase cannot be empty; Chute refuses to load a PKCS#12 without one. Use "base64" command to encode in base64 string and append these settings below to your config file.

[MITM]
enable = true
ca-p12 = MIIJtQ.........
ca-passphrase = password
hostname = *google.com

Chute only decrypts traffic to hosts declared here, so always set it. On every platform an enabled [MITM] section that declares no hostname decrypts nothing, whether the key is missing altogether or only hostname-disabled entries are given. Through the HTTP proxy, only HTTPS that arrives by CONNECT is decrypted: a plain HTTP request is forwarded as usual, even when its host is listed in hostname.

Wildcard characters and ? are supported. Note that ? only acts as a wildcard when the rule also contains `; a rule containing only?` is compared literally.

  • Use prefix - to exclude a hostname. Entries are checked in the order they are written, and the first one that matches decides, so an exclusion has to come before the entry it carves out of: hostname = -*.apple.com, * leaves apple.com alone, while hostname = *, -*.apple.com decrypts it.
  • By default, only the requests to port 443 be decrypted.
    • Use suffix :port to allow other ports.
    • Use suffix :0 to allow all ports.

Example:

  • -*.apple.com: Excludes all requests sent to *.apple.com on port 443.
  • www.google.com: Allows MitM for www.google.com on port 443.
  • www.google.com:8080: Allows MitM for www.google.com on port 8080.
  • www.google.com:0: Allows MitM for www.google.com on all ports.
  • *: Allows MitM for all hostnames on port 443. (Not Recommended)
  • *:0: Allows MitM for all hostnames on all ports. (Not Recommended)

Four keywords stand for whole classes of destination and take the same - prefix and :port suffix as a name: <ip-address> (any connection made to an IP literal), <ipv4-address>, <ipv6-address> and <simple-hostname> (a name with no dot, such as intranet). hostname = -<simple-hostname>, * decrypts everything except single-label names, and hostname = <ip-address> decrypts only connections made to an address. The address keywords only ever apply to a CONNECT to an address through the HTTP proxy: a TUN connection is decrypted only by host name — the one Chute resolved for it, or the server name in its TLS handshake when sniffing-enabled is on — so one made to a bare address with no server name is never decrypted.

A hostname entry may also include a path pattern after the first /. The decision to decrypt is made when the connection opens — at the CONNECT, or when a TUN session starts — before any request path is known, so a path-scoped entry decrypts the whole connection on a host match, and a -host/path exclusion does not take effect at all. Do not rely on it to keep a host out of decryption.

  • example.com/api/*: Allows MitM for example.com on port 443; the path does not narrow it.

A general configuration may be like:

hostname = -*.apple.com, -*.icloud.com, *

Chute will apply URL Rewrite, Header Rewrite, Body Rewrite and Mock Response ([Map Local]) rules as well as scripts to all MitM requests — every request on a decrypted connection, not only its first. A decrypted HTTP/1.1 connection carries one exchange: Chute closes it once the response is out, so the client sends its next request on a new connection, which is handled the same way; a request pipelined behind the first on the same connection is not processed, and the client sends it again on the new one. The exception is a connection Chute Android decrypts from the VPN, which stays open while each request on it is handled in turn. It is closed after an answer Chute makes itself — a Mock Response, a URL Rewrite answer, a script's response — and after a response whose body came from an http-response script that ran on the headers. HTTP/2 connections keep their connection, and so does a WebSocket upgrade: after the 101 response, data passes unchanged both ways.

MitM supports HTTP/2, through the HTTP proxy and through TUN alike. Before its TLS handshake with the server, Chute reads the protocols the client offers (ALPN): when the client offers h2 and [MITM] does not set h2 = false, the server is offered h2 and http/1.1, otherwise http/1.1 only. The client is then offered the protocol the server chose, so both sides speak the same one; when the client did not offer that protocol, Chute gives no ALPN answer and the handshake goes on. On HTTP/2, trailers (gRPC's grpc-status, for one) and interim 1xx responses such as 103 Early Hints are passed on as they are; rules and scripts do not see them. Surge's [MITM] key tcp-connection is accepted in config files but ignored.

Some applications has strict security policy to use pinned certificates or CA. Enabling decryption to these hosts may casue problems.

Chute keeps the host certificates it has minted in a store and evicts the least recently used one when it is full: 512 certificates on macOS, 128 on iOS, tvOS and Android.

Installing and trusting the CA certificate

Generating (or importing) the CA is only half of the setup — the operating system must also trust it. Until both steps are done, every decrypted site fails with a certificate warning. The certificate page in the app shows the current state ("Trusted CA Certificate" / "Not Trusted CA Certificate").

Chute iOS — in the configuration editor open MITM → Configure CA:

  1. Generate A New CA Certificate (or Import P12 Certificate for an existing one).
  2. Tap Install CA Certificate to System. A Safari page opens — tap Install Certificate and allow the download, then install the downloaded profile under Settings → General → VPN & Device Management.
  3. Trust it: Settings → General → About → Certificate Trust Settings, and enable full trust for the Chute CA. This step is the one most people miss — without it the certificate is installed but not trusted, and decryption keeps failing.

Chute Mac — in the configuration window open MitM:

  1. Generate New Certificate (or Import Certificate from PKCS#12 File).
  2. Click Install the Certificate to System. macOS asks for an administrator password and adds the certificate to the System keychain as a trusted root — no manual Keychain Access steps are needed.
  3. Export the Certificate saves a .pem copy for installing on other devices.

Chute Android — in the configuration editor open MitM → Configure CA:

  1. Import P12 writes an existing PKCS#12 into ca-p12 as base64, as the Apple apps do, so the configuration carries its CA to other devices; enter its passphrase in CA Passphrase. Chute Android has no generator. A ca-p12 that names a file, as earlier versions of the editor wrote it, is still read.
  2. Install CA hands the CA certificate in that P12 to Android's certificate installer. From Android 11 on, an app can no longer install a CA certificate that way: install it from a certificate file in the system's security settings instead — a .pem or .crt copy of it, such as the one Export the Certificate saves on Chute Mac.
  3. Android keeps it among the user's certificates, and apps that target Android 7.0 or later trust those only when they opt in. Many apps therefore still fail the handshake after the certificate is installed — exclude their hosts from hostname.

If a specific app still fails with a trusted certificate, it most likely pins its own certificates — exclude its hosts from hostname with a - prefix instead of fighting it.

Options

skip-server-cert-verify

skip-server-cert-verify = true

Do not verify the certificate of the remote host while performing MitM. When enabled, Chute will accept any certificate presented by the upstream server, including self-signed or invalid certificates. This is useful for development environments but reduces security.

[MITM]
enable = true
ca-p12 = MIIJtQ.........
ca-passphrase = password
skip-server-cert-verify = true
hostname = *google.com

Security Note: Enabling skip-server-cert-verify makes MitM connections vulnerable to man-in-the-middle attacks between Chute and the upstream server. Only enable this for trusted networks or development purposes.

hostname-disabled

hostname-disabled = *.bank.example, pay.example.com:8443

Hosts that are never decrypted, even when an entry in hostname covers them. Wildcards work as in hostname, and :port limits an entry to one port. Handy for turning off hosts that a module added without editing the module.

auto-quic-block

auto-quic-block = true

Blocks QUIC to every host that would be decrypted, so HTTP/3 clients fall back to TLS over TCP, where MitM can see the traffic. It works in addition to block-quic, not instead of it.

S. Smart Rabbit LLC © All Rights Reserved            updated 2026-09-25 00:02:29

results matching ""

    No results matching ""