Skip to content

HTTPS Decryption Overview

HTTPS decryption (also called MITM, “man in the middle”) lets MeowX look inside encrypted HTTPS requests for the hosts you choose, so that rules can block, redirect, rewrite or record them. It works with the large ecosystem of Surge modules and Loon plugins, and it is also a practical debugging tool for your own apps and services.

Everything happens on your device. MeowX generates a certificate authority (CA) unique to your device, your device trusts it, and MeowX uses it to sign a certificate for each host it decrypts. No traffic, certificates or recorded requests are uploaded anywhere.

Ad and pop-up blocking

Most modules people install are ad blockers: they reject ad and tracking URLs, replace splash-screen API responses with empty ones, or strip fields from JSON responses.

Fixing and redirecting

Redirect URLs with 302 / 307, rewrite request or response headers, or serve a local response instead of contacting the server.

Debugging

Record decrypted requests and responses, including bodies, then copy them as cURL commands or export them as HAR files.

Scripts

Run Surge-style JavaScript on requests and responses. See the responsible-use notice on the Scripts page.

  1. Certificate. You generate a CA in MeowX and install and trust it in the system (see Certificate). The private key never leaves the device.
  2. Hostname list. Only HTTPS connections whose host matches the hostname list are decrypted. Hostnames come from you and from your enabled modules. Every other HTTPS connection is passed through untouched.
  3. Two TLS handshakes. For a listed host, MeowX first connects to the real server (through whatever outbound your proxy rules select) and verifies its certificate, then completes a handshake with the app using a certificate it signs on the fly for that hostname.
  4. Rules. Each request and response then runs through your local rules and your modules: header rewrites, URL rewrites, Map Local, body rewrites and scripts.

If anything goes wrong on the server side before the app has received a single byte from MeowX (the server only supports TLS 1.2, demands a client certificate, presents an untrusted certificate, and so on), MeowX quietly falls back to passthrough: the connection is forwarded unchanged and the app behaves exactly as if decryption were off. Diagnostics tells you why a host was not decrypted.

Unencrypted http:// requests do not need a certificate or a hostname list. While the HTTPS Decryption switch is on, plain HTTP requests on ports 80, 8080, 8000 and 8880 (plus any port you write explicitly in the hostname list) are processed by the same rules, as long as at least one rule could match the request’s host. This keeps working even before the certificate is trusted.

The order follows Surge’s HTTP processing:

Stage Request Response
1 Header rewrite (every matching rule, in order) Header rewrite (every matching rule, in order)
2 URL rewrite (first matching rule only) Body rewrite (every matching rule, in order)
3 Map Local (first matching rule, only if no URL rewrite answered locally) Response scripts
4 Body rewrite (every matching rule, in order)
5 Request scripts

All rules, including response-side rules, match against the original URL the app requested. A transparent URL rewrite only changes what is sent upstream; it does not change which later rules match.

  1. Open the HTTPS Decryption settings: on iPhone and iPad go to Me → HTTPS Decryption (MITM); on the Mac open the menu bar panel and choose Settings → Overrides → HTTPS Decryption (MITM), which opens a separate HTTPS Decryption window.

  2. Generate the certificate and install and trust it. On iOS this takes about a minute and five steps; on the Mac it is a single Install and Trust button. See Certificate.

  3. Turn on the HTTPS Decryption switch. The first time, MeowX shows a short summary of what this means before it turns on.

  4. Add hostnames yourself, or install a module that brings its own hostnames and rules.

  5. Use your apps as normal. Changes apply to new connections right away; you don’t need to reconnect. Open Diagnostics or Request Records to see what is being decrypted.

Switch Certificate What happens
Off any Neither plain HTTP nor HTTPS traffic is touched.
On not trusted (or not generated) Plain HTTP is rewritten according to your rules. HTTPS is not decrypted; the page shows “HTTPS decryption not active” with a button to fix the certificate.
On trusted Listed HTTPS hosts are decrypted, and plain HTTP is rewritten.

Routing rules in a module’s [Rule] section are not affected by this switch: they follow the module’s own on/off switch. See Modules.

HTTPS decryption is powerful, so MeowX is deliberately conservative:

  • Only listed hosts are decrypted. Everything else is forwarded without being read. A module’s hostnames are only used when at least one of its supported rules can actually match them, so hosts that a module only mentions for unsupported rules stay encrypted.
  • Your exclusions always win. Hostnames you exclude with a leading - are checked first, before built-in exclusions and before anything a module inserts. A module cannot override your exclusions or remove them.
  • Built-in exclusions. *.apple.com, *.icloud.com, *.mzstatic.com, *.push.apple.com and the bare domains apple.com, icloud.com and mzstatic.com are excluded by default, because most Apple system services use certificate pinning. You can remove them; modules cannot.
  • Always-direct traffic is never decrypted. Your provider’s dashboard and its subscription domains, the bypass list and Apple Push Notification service (APNs) always connect directly and are never decrypted. Modules cannot change this.
  • Modules can never turn off certificate verification. MeowX always verifies the real server’s certificate. A skip-server-cert-verify line in a module is ignored and shown as “Ignored: security reasons”. Only you can turn on Skip upstream certificate verification in the Advanced section.
  • Sensitive-host warnings. MeowX recognizes banking, payment, government, sign-in (SSO) and password-manager hosts. When a module wants to decrypt them, the install confirmation lists them separately and you must explicitly acknowledge them. Recorded requests to these hosts are masked and their bodies are not recorded.
  • Install and update confirmation. Every module install, including one started from a meowx://install-module link, goes through a confirmation page first. Remote updates that widen what a module can do (new hosts, new or changed scripts, redirects to other hosts, rules on sensitive hosts and more) wait for your approval. See Remote updates.
  • Devices on your network are not decrypted. Connections arriving at the local proxy from other devices on your LAN are always passed through; they don’t trust your device’s CA.
  • Nothing leaves your device. The CA private key is stored only in this device’s keychain, excluded from backups and iCloud sync. Recorded requests live only in memory and are cleared when you disconnect.
  • MeowX doesn’t ship or recommend modules. There is no built-in module catalog. Install only modules from sources you trust.
  • Connections to hosts that are not in the list cost almost nothing: MeowX decides from information it already has and does not read extra data.
  • Each decrypted connection costs two TLS handshakes, encrypting and decrypting every byte twice, and HTTP parsing. On a handful of hosts this is negligible.
  • Writing * (all hosts) decrypts every HTTPS connection. CPU use and battery drain rise noticeably and apps with certificate pinning will break widely. MeowX asks for confirmation when you add *, and it is not recommended on iPhone.
  • HTTP/2 is used automatically when both the app and the server support it, so one decrypted connection can carry many requests. See Diagnostics.
  • There are limits on simultaneous decrypted connections (64 on iOS, 256 on macOS) and on memory. When a limit is reached, new connections are passed through and counted as “Too many decrypted connections”. See Limits.
  • Body rewrites and scripts need the whole body in memory, so they are capped in size and run one at a time on iOS.
iPhone and iPad Mac
Where to find it Me → HTTPS Decryption (MITM) Menu bar panel Settings → Overrides → HTTPS Decryption (MITM) opens a separate window
Installing the certificate Download a profile with Safari, install it in Settings, then enable full trust One Install and Trust button; the system asks for your password or Touch ID
Request records Activity tab → Requests, or Request Records in the settings Requests page in the HTTPS Decryption window
Body buffer per message 512 KB 10 MB

On the Mac, the HTTPS Decryption window has a sidebar with Overview, Hostnames, Modules, Local Rules, Requests, Diagnostics and What Can’t Be Decrypted. It remembers its size and position and closing it does not quit MeowX. The menu bar panel keeps only the settings row (which shows the current state, such as Off, Active, Certificate not trusted or Needs reconnect) and the Decrypt this host button in connection details.

HTTPS decryption works in both of the Mac’s modes: TUN mode and system proxy mode. In system proxy mode only apps that honor the system proxy pass through MeowX.

Some connections are always passed through, whatever you configure: apps with certificate pinning, apps that use only QUIC and never fall back to TCP, TLS 1.2-only apps or servers, servers that require a client certificate, connections using real ECH, connections to bare IP addresses without a hostname, and (because iOS doesn’t say which app opened a connection) per-app selection. On the Mac, services running as root and command-line tools such as curl, Python and Node, which don’t read the login keychain, don’t trust the certificate. The full list is on the Limits page.