---
title: "O que é um proxy MITM? Guia de Charles, Fiddler e mitmproxy"
description: "Um proxy MITM passa o seu próprio tráfego por uma ferramenta local para você ler requisições e respostas HTTPS. Comparamos Charles, Fiddler e mitmproxy."
url: https://proxynet.io/pt-br/blog/mitm-proxy
date: 2026-09-24
author: "Acar Diveroli"
category: "Proxy 101, Tutoriais"
lang: pt-BR
---

# O que é um proxy MITM? Guia de Charles, Fiddler e mitmproxy

O seu scraper recebe um `403` em uma página de categoria que abre sem problema no navegador, e o erro não diz nada além do código de status. Lado a lado, a requisição do navegador e a do Python mostrariam a diferença em um minuto, mas o HTTPS mantém as duas lacradas. Um proxy MITM no seu próprio computador abre esse lacre só para você.

Este guia explica como um proxy MITM lê HTTPS, compara Charles, Fiddler e mitmproxy com as condições de licença de 2026 e trata do certificado raiz, dos seus próprios apps móveis, de uma configuração em Python testada e do encadeamento com um proxy upstream. Tudo parte do princípio de que o dispositivo e o app são seus, ou de que você tem permissão por escrito para testar o sistema.

> **Nota: Resposta rápida**
>
> Um proxy MITM é uma ferramenta de depuração que fica entre o seu navegador, script ou app e a internet, no seu próprio computador. Para ler HTTPS, ele cria na hora um certificado para cada site e o assina com um certificado raiz local gerado na primeira execução. Esse certificado raiz só deve ficar no seu dispositivo de teste, e só durante o teste. O Charles é um app de desktop pago, o Fiddler Everywhere funciona por assinatura, o Fiddler Classic tem licença só para uso não comercial desde 3 de agosto de 2026, e o mitmproxy é open source e programável em Python.

## O que é um proxy MITM?

“Man-in-the-middle” (homem no meio) é o nome de um ataque: alguém se coloca entre duas partes sem que elas saibam e lê o que elas enviam. Um proxy MITM usa a mesma posição para depuração. Você instala a ferramenta, o tráfego é seu e você mesmo confia no certificado dela, então ninguém é enganado. Empresas usam a técnica para inspeção TLS nos computadores dos funcionários; esse lado fica para [proxy vs firewall](/pt-br/blog/proxy-vs-firewall).

Um forward proxy comum ([como funciona um servidor proxy](/pt-br/blog/what-is-a-proxy-server)) vê só o host de destino de uma requisição HTTPS, pela linha `CONNECT example.com:443`, e depois transporta bytes criptografados. Um proxy MITM encerra a conexão criptografada na sua máquina, então vê a URL completa, cada cabeçalho e o corpo.

## Como um proxy MITM abre o tráfego HTTPS?

A [RFC 9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-connect) descreve um túnel como um repasse cego, que passa as mensagens adiante sem alterá-las. Um proxy comum segue essa regra depois do `CONNECT`; um proxy MITM a quebra de propósito, para os clientes que confiam no certificado dele. Seguindo a [descrição do fluxo feita pelo mitmproxy](https://docs.mitmproxy.org/stable/concepts/how-mitmproxy-works/):

1. O cliente envia `CONNECT example.com:443` para a ferramenta local.
2. A ferramenta responde `200 Connection Established`, como se tivesse aberto o túnel.
3. O cliente inicia o handshake TLS e informa o host no campo SNI.
4. A ferramenta se conecta a esse host por TLS e lê os nomes (CN e SAN) do certificado do servidor.
5. Ela cria um certificado com esses nomes e o assina com o seu certificado raiz local (a CA, autoridade certificadora).
6. Se o cliente confia nessa CA, o handshake termina, e a ferramenta lê o tráfego em texto puro antes de criptografá-lo de novo em direção ao servidor.

Se o cliente não confia na CA, o passo 6 falha com um erro de certificado, como deve ser. Um gateway da Proxynet nunca executa o passo 5: ele repassa o túnel `CONNECT` às cegas, por isso um [Proxies HTTPS](https://proxynet.io/pt-br/https-proxy) não precisa de certificado raiz no seu dispositivo.

## Comparação entre Charles, Fiddler e mitmproxy

Com base nas páginas dos próprios fornecedores em setembro de 2026; só modelos de licença, sem preços.

| Ferramenta | Licença | Plataformas | Interface | Porta padrão | Proxy upstream | Automação |
|---|---|---|---|---|---|---|
| Charles | Licença de usuário paga após 30 dias de teste | Windows, macOS, Linux | App de desktop | Geralmente 8888 | HTTP, HTTPS e SOCKS; autenticação Basic ou NTLM | Breakpoints, Rewrite, Map Local |
| Fiddler Everywhere | Assinatura, 10 dias de teste | Windows, macOS, Linux | App de desktop | 8866 | String de proxy manual; autenticação Kerberos, Negotiate ou NTLM | Rules |
| Fiddler Classic | Só uso não comercial desde 3 de agosto de 2026 | Só Windows | App de desktop | 8888 | Não tratado aqui | FiddlerScript |
| mitmproxy | Open source, MIT | Windows, macOS, Linux | Terminal, navegador (`mitmweb`), linha de comando (`mitmdump`) | 8080 | `--mode upstream:` com `upstream_auth` (Basic) | Addons em Python, CI |

O Charles e o Fiddler Everywhere são indicados para equipes de QA de apps móveis que editam requisições em uma janela; o mitmproxy, para desenvolvedores que querem a verificação em uma suíte de testes ou no CI, onde cada passo é uma função Python. O Burp Suite é voltado para testes de segurança, que ficam fora deste guia.

## O que é o Charles Proxy e quando escolhê-lo?

O Charles é um app de desktop que você pode testar por 30 dias antes de comprar uma licença de usuário. Ele descriptografa só os hosts da sua lista de [SSL Proxying](https://www.charlesproxy.com/documentation/proxying/ssl-proxying/) (`*` significa todos os hosts) e encaminha o restante do tráfego HTTPS sem abrir. Um testador aponta o proxy do Wi-Fi do iPhone para o notebook e a porta 8888, permite o aparelho quando o Charles pergunta e depois usa Breakpoints para editar requisições, Map Local para responder a partir de um arquivo e o throttling (limitação de banda) para simular uma rede lenta.

## O que é o Fiddler? Classic e Everywhere

O **Fiddler Classic** roda só no Windows, não é mais desenvolvido e tem o FiddlerScript. Desde 3 de agosto de 2026, a licença dele permite só uso não comercial; os usuários comerciais tiveram até 17 de setembro de 2026 para migrar, e [não existe licença paga do Classic](https://www.telerik.com/fiddler/fiddler-classic/commercial-use).

O **Fiddler Everywhere** é o produto comercial: Windows, macOS e Linux, assinatura depois de 10 dias de teste, suporte a HTTP/2 e TLS 1.3, e porta 8866. Você ativa a captura de HTTPS, confia no certificado raiz dele e filtra as sessões por host.

## O que é o mitmproxy? Três interfaces e addons em Python

O mitmproxy tem licença MIT; a versão 12.2.3 (12 de maio de 2026) exige Python 3.12 ou mais recente. Ele traz o `mitmproxy` (visão no terminal), o `mitmweb` (visão no navegador) e o `mitmdump` (sem interface, para scripts e CI), todos na porta 8080 por padrão.

Na primeira execução, ele [cria a sua CA](https://docs.mitmproxy.org/stable/concepts/certificates/) em `~/.mitmproxy`, única para aquela instalação: a chave privada (`mitmproxy-ca.pem`) fica ao lado dos arquivos de certificado para cada plataforma (`mitmproxy-ca-cert.pem`, `.p12`, `.cer`). Com o proxy configurado em um dispositivo, `mitm.it` oferece o arquivo certo e os passos de instalação. Um addon é um arquivo Python cujas funções têm o nome de eventos como `response`.

## Por que é preciso um certificado raiz, e ele é seguro?

Quem tem a chave privada de uma CA pode criar um certificado que parece válido para qualquer site em todos os dispositivos que confiam nela. O risco está nessa chave, não na ferramenta:

- **Só uma CA gerada pela sua própria ferramenta.** O nosso [guia sobre a segurança de proxies gratuitos](/pt-br/blog/are-free-proxies-safe) diz para não instalar um certificado que um serviço de proxy pede, e isso continua valendo: uma CA remota permite que um estranho leia o seu tráfego. Uma ferramenta no seu próprio computador é diferente, porque a chave dela nunca sai da sua máquina.
- **Só em dispositivos de teste, só durante o teste.** Não compartilhe nem faça commit de `~/.mitmproxy`, e remova a CA ao terminar.
- **Mantenha as verificações da ferramenta ligadas.** A opção `ssl_insecure` do mitmproxy pula a verificação de certificado em direção ao servidor, e o texto de ajuda dela avisa que isso deixa o próprio mitmproxy exposto a interceptação.

Para remover a CA:

- **Windows:** `certmgr.msc` > Autoridades de Certificação Raiz Confiáveis > Certificados.
- **macOS:** apague o certificado da ferramenta no app Acesso às Chaves.
- **iPhone:** Ajustes > Geral > Gerenciamento de Dispositivo e VPN > o perfil > Remover Perfil.
- **Android (Pixel):** Configurações > Segurança e privacidade > Mais configurações de segurança > Criptografia e credenciais > Credenciais do usuário; em outros fabricantes, o caminho muda antes dos dois últimos passos.

## Ver o tráfego do seu próprio app no Android e no iPhone

Aponte o proxy do Wi-Fi do celular para o endereço IP do seu computador e a porta da ferramenta, usando as [configurações de proxy no Android](/pt-br/blog/android-proxy-settings) ou as [configurações de proxy no iPhone](/pt-br/blog/iphone-proxy).

**Android.** Segundo a documentação da [configuração de segurança de rede](https://developer.android.com/privacy-and-security/security-config), apps voltados ao Android 7.0 (API de nível 24) ou mais recente confiam por padrão só nas CAs do sistema, então o seu app pode falhar com um erro de TLS enquanto o navegador funciona. No seu próprio app, adicione um bloco `debug-overrides`:

```xml
<!-- res/xml/network_security_config.xml -->
<network-security-config>
    <debug-overrides>
        <trust-anchors>
            <certificates src="user" />
        </trust-anchors>
    </debug-overrides>
</network-security-config>
```

Referencie o arquivo com `android:networkSecurityConfig="@xml/network_security_config"` no manifesto. O Android ignora o bloco quando `android:debuggable` é false, então um build de release mantém as regras normais de confiança.

**iPhone.** Depois de instalar o perfil, ative a confiança total em [Ajustes > Geral > Sobre > Certificados Confiáveis](https://support.apple.com/pt-br/102390).

**Pinning.** Um app que faz pinning de certificados recusa o certificado da ferramenta. No seu próprio app, ajuste o pinning no build de teste; no app de outra pessoa, o pinning é uma decisão do desenvolvedor, e este guia para aí.

## Interceptar, editar e reenviar requisições

As três ferramentas permitem pausar uma requisição e mudar um cabeçalho antes que ela saia, responder a uma requisição com um arquivo local para testar uma tela de erro e enviar de novo uma requisição salva, de modo que um bug que aparece uma vez por dia pode ser repetido quando você quiser. No mitmproxy, `-w flows.mitm` salva os fluxos e `-C flows.mitm` os reenvia. Reenvie só para a sua própria API ou para um endpoint que você tenha permissão para testar, dentro dos limites de taxa dele.

Para a requisição em segundo plano de uma página web, o DevTools basta ([como encontrar a requisição XHR](/pt-br/blog/static-vs-dynamic-pages)); a ferramenta local é para scripts e apps.

## Depurar um scraper em Python com um proxy MITM

De volta ao `403`: passamos o script pelo `mitmdump`, registramos cada resposta e imprimimos os detalhes da requisição em cada erro. Testado com Python 3.13, mitmproxy 12.2.3 e Requests 2.34.2 (`pip install mitmproxy requests`).

O addon, `debug_addon.py`, imprime uma linha por resposta e, em `4xx` e `5xx`, os cabeçalhos que costumam diferir dos de um navegador, se um cookie foi enviado e o início do corpo:

```python
"""Addon do mitmdump: uma linha por resposta, detalhes da requisição em cada 4xx e 5xx."""
from mitmproxy import http

WATCH = ("User-Agent", "Accept", "Accept-Language", "Accept-Encoding")

def response(flow: http.HTTPFlow) -> None:
    req, resp = flow.request, flow.response
    print(f"{resp.status_code} {req.method} {req.pretty_url}")
    if resp.status_code < 400:
        return
    for name in WATCH:
        print(f"    {name}: {req.headers.get(name, '(not sent)')}")
    print(f"    Cookie: {'sent' if 'Cookie' in req.headers else 'not sent'}")
    body = resp.get_content(strict=False) or b""  # descomprimido se vier em gzip ou br
    print(f"    body: {body[:300].decode('utf-8', 'replace')!r}")
```

O script, `scraper_debug.py`, usa o proxy só quando `DEBUG_PROXY` está definida e confia na CA local por meio de `verify`. A documentação do Requests avisa que [`verify=False` deixa a aplicação vulnerável a ataques MitM](https://requests.readthedocs.io/en/latest/user/advanced/), por isso ele nunca aparece aqui:

```python
"""Busca páginas com Requests; defina DEBUG_PROXY para passá-las por um mitmdump local."""
import os
import sys
from pathlib import Path

import requests

DEBUG_PROXY = os.environ.get("DEBUG_PROXY")  # ex.: http://127.0.0.1:8080
MITM_CA = Path.home() / ".mitmproxy" / "mitmproxy-ca-cert.pem"

session = requests.Session()
session.headers.update({
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                  "(KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
    "Accept-Language": "en-GB,en;q=0.9",
})

def request_options():
    options = {"timeout": (5, 30)}  # (conexão, leitura) em segundos
    if DEBUG_PROXY:
        if not MITM_CA.is_file():
            sys.exit(f"{MITM_CA} not found: start mitmdump once, it creates the CA there.")
        # Passado por requisição: um valor em Session.proxies pode ser sobrescrito por HTTPS_PROXY.
        options["proxies"] = {"http": DEBUG_PROXY, "https": DEBUG_PROXY}
        options["verify"] = str(MITM_CA)  # confia na CA local, nunca verify=False
    return options

def fetch(url):
    try:
        return session.get(url, **request_options())
    except requests.exceptions.SSLError as exc:
        sys.exit(f"TLS check failed for {url}: is {MITM_CA} the CA of the "
                 f"mitmdump that is running?\n{exc}")
    except requests.exceptions.ProxyError as exc:
        sys.exit(f"Debug proxy {DEBUG_PROXY} did not answer: is mitmdump running?\n{exc}")

if __name__ == "__main__":
    for url in sys.argv[1:] or ["https://httpbin.org/headers"]:
        resp = fetch(url)
        print(resp.status_code, url)
        for name, value in resp.request.headers.items():
            print(f"    {name}: {value}")
```

Inicie o `mitmdump` só no endereço de loopback:

```bash
mitmdump --listen-host 127.0.0.1 -p 8080 -s debug_addon.py -w flows.mitm
```

Depois rode o script em um segundo terminal (no PowerShell, defina antes `$env:DEBUG_PROXY = "http://127.0.0.1:8080"`):

```bash
DEBUG_PROXY=http://127.0.0.1:8080 python scraper_debug.py https://httpbin.org/headers https://httpbin.org/status/403
```

A janela do `mitmdump` imprimiu isto (linhas de conexão removidas):

```text
200 GET https://httpbin.org/headers
403 GET https://httpbin.org/status/403
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36
    Accept: */*
    Accept-Language: en-GB,en;q=0.9
    Accept-Encoding: gzip, deflate, br
    Cookie: not sent
    body: ''
```

Agora abra a página em um navegador configurado com o mesmo proxy. `Accept: */*` contra o `text/html,...` do navegador, ou um cookie ausente de uma página anterior, são achados típicos; o segundo significa que o script pulou uma etapa ([sessões e cookies em Python](/pt-br/blog/python-login-session-cookies)). Se o site recusa de propósito clientes que não são navegadores, essa é a resposta dele: use a API do site ou peça permissão.

Um arquivo de CA errado interrompeu o script com `CERTIFICATE_VERIFY_FAILED` e a nossa dica. `mitmdump --set server=false -C flows.mitm -s debug_addon.py` reenviou as duas requisições e terminou sem abrir uma porta de escuta.

O servidor vê o handshake TLS da ferramenta, não o do seu script, então um site que verifica [fingerprints TLS](/pt-br/blog/tls-fingerprinting) pode responder de outro jeito enquanto a ferramenta está ligada; compare com uma execução sem `DEBUG_PROXY`. As novas tentativas para `429` estão em [códigos de status HTTP no web scraping](/pt-br/blog/http-status-codes-web-scraping), as variáveis de ambiente em [proxy no wget](/pt-br/blog/wget-proxy), a rotação em [como rotacionar proxies em Python](/pt-br/blog/how-to-rotate-proxies-in-python) e a escolha de biblioteca em [HTTPX, Requests ou AIOHTTP](/pt-br/blog/httpx-vs-requests-vs-aiohttp).

## Testar de outro país: encadear a ferramenta local a um proxy

Para ver os preços que o seu app mostra a um usuário na Alemanha, envie o tráfego do dispositivo para a ferramenta MITM local (onde acontece a descriptografia), dali para um proxy upstream e depois para o destino. Em destinos HTTPS, o proxy upstream só transporta o túnel criptografado de novo; a Proxynet não o descriptografa.

**mitmproxy.** O modo upstream encaminha cada requisição, e `upstream_auth` adiciona autenticação Basic:

```bash
mitmdump --listen-host 127.0.0.1 --mode upstream:http://pr.proxynet.io:8000 --set upstream_auth=user:pass -s debug_addon.py
```

Testamos isso contra um proxy local que exige senha. Com uma senha errada, o script recebeu um `502` do `mitmdump`, e o log dele mostrou a causa: o upstream recusou o `CONNECT` com `407`.

**Charles.** O recurso [External Proxies](https://www.charlesproxy.com/documentation/configuration/external-proxies/) aceita endereços separados para HTTP, HTTPS e SOCKS, com autenticação Basic ou NTLM e uma lista de exceções com curingas.

**Fiddler Everywhere.** Em Settings > Gateway você informa uma string de proxy manual, e a documentação lista [Kerberos, Negotiate e NTLM](https://www.telerik.com/fiddler/fiddler-everywhere/documentation/installation-and-setup/advanced-installation/configuring-fiddler-alongside-proxy-auth) para a autenticação no upstream, não usuário e senha. Com a Proxynet, autorize em vez disso o endereço IP do seu computador ([user:pass e whitelist de IP](/pt-br/blog/proxy-authentication-methods)).

Use um [Proxies móveis](https://proxynet.io/pt-br/mobile-proxy) para um IP de operadora ou um [Proxies residenciais](https://proxynet.io/pt-br/residential-proxy) para uma conexão residencial; o cenário completo está na nossa página de [teste de apps](/pt-br/app-testing).

## Para que se usa um proxy MITM?

- **Scraper vs navegador:** encontre o cabeçalho que transforma `200` em `403` ([códigos de status HTTP](/pt-br/blog/http-status-codes-web-scraping)).
- **Postman:** veja os cabeçalhos finais que o Postman envia ([configurações de proxy no Postman](/pt-br/blog/postman-proxy)).
- **O seu próprio app:** acompanhe chamadas de API e erros em um celular de teste ([teste de apps](/pt-br/app-testing)).
- **Cabeçalhos de proxy:** identifique `Via` ou `X-Forwarded-For` em HTTP sem criptografia ([níveis de anonimato de proxy](/pt-br/blog/anonymous-proxy-levels)).
- **Um `407`:** confira se as credenciais chegam ao proxy upstream ([métodos de autenticação de proxy](/pt-br/blog/proxy-authentication-methods)).
- **Verificação de proxies:** confirme a saída e as respostas antes de um trabalho ([como testar um proxy](/pt-br/blog/how-to-test-a-proxy)).

## Erros comuns

- **Deixar a CA instalada.** Quem obtiver a chave depois pode se passar por qualquer site para aquele dispositivo.
- **Publicar código com `verify=False`.** Aponte `verify` para o arquivo da CA.
- **Esperar que um app Android confie em uma CA de usuário.** Apps voltados à API de nível 24+ a ignoram fora de um build de debug que a permita.
- **Esquecer o SSL Proxying para o host no Charles.** Você vê entradas `CONNECT` criptografadas e nenhum conteúdo.
- **Escutar em todas as interfaces.** Sem `--listen-host`, o `mitmdump` escutou em `0.0.0.0` e `::` no nosso teste; use `127.0.0.1`, a menos que um celular precise se conectar.
- **Compartilhar arquivos de fluxo sem cuidado.** Eles guardam cookies e cabeçalhos.
- **Usar o Fiddler Classic no trabalho depois de agosto de 2026.** A licença dele é só para uso não comercial.

## Guia de decisão

| Necessidade | Recomendação |
|---|---|
| Comparar a requisição de um scraper com a do navegador | mitmproxy com um addon pequeno; `verify` do Requests apontado para o arquivo da CA |
| Editar requisições em uma janela para QA de apps móveis | Charles ou Fiddler Everywhere |
| Fiddler para trabalho comercial no Windows | Fiddler Everywhere ou outra ferramenta, não o Fiddler Classic |
| Tráfego HTTPS do seu próprio app Android | `debug-overrides` só no build de debug |
| Testar o seu app como um usuário de outro país | Encadear a ferramenta local a um proxy móvel ou residencial ([teste de apps](/pt-br/app-testing)) |
| Encontrar a requisição em segundo plano de uma página web | A aba Network do DevTools; não é preciso ferramenta MITM |

## Perguntas frequentes

### É legal usar um proxy MITM?

No seu próprio dispositivo e app, ou em um sistema que você tem permissão por escrito para testar, é uma ferramenta de depuração. Ler o tráfego de outras pessoas às escondidas é outra coisa. Sobre scraping, veja [web scraping é legal?](/pt-br/blog/is-data-web-scraping-legal).

### O mitmproxy é seguro?

A ferramenta é open source e roda localmente. O risco é a chave privada da CA em `~/.mitmproxy`: mantenha essa chave privada, instale a CA só em dispositivos de teste e remova a CA depois.

### O Fiddler Classic ainda é gratuito, e qual a diferença para o Fiddler Everywhere?

Desde 3 de agosto de 2026, o Fiddler Classic é gratuito só para uso não comercial; ele roda no Windows e não é mais desenvolvido. O Fiddler Everywhere é o produto pago e multiplataforma, com suporte a HTTP/2 e TLS 1.3.

### Existe alternativa gratuita ao Charles Proxy?

O mitmproxy é open source e roda nas mesmas plataformas; o `mitmweb` dá a ele uma visão no navegador. O próprio Charles tem 30 dias de teste.

### Instalei o certificado no Android. Por que o tráfego do meu app ainda não aparece?

Apps voltados à API de nível 24 ou mais recente confiam por padrão só nas CAs do sistema. Permita CAs de usuário no build de debug do seu próprio app com `debug-overrides`, e ajuste o pinning no build de teste se o app fizer pinning de certificados.

### Qual a diferença entre um proxy MITM, um proxy comum e uma VPN?

Um proxy comum e uma VPN transportam o tráfego criptografado sem lê-lo e mudam o seu IP de saída ([proxy vs VPN](/pt-br/blog/proxy-vs-vpn)). Um proxy MITM abre esse tráfego no seu computador e mantém o seu IP, a menos que seja encadeado a um proxy upstream.

## Em resumo

Um proxy MITM é uma ferramenta para ler o seu próprio tráfego, com uma CA que fica local, temporária e só em dispositivos de teste. O Charles e o Fiddler Everywhere combinam com trabalho em uma janela; o mitmproxy combina com scripts e CI. Quando um teste precisa vir de outro país, encadeie a ferramenta local a um proxy upstream, começando pela nossa página de [teste de apps](/pt-br/app-testing).
