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.
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.
Um forward proxy comum (como funciona um servidor proxy) 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 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:
- O cliente envia
CONNECT example.com:443para a ferramenta local. - A ferramenta responde
200 Connection Established, como se tivesse aberto o túnel. - O cliente inicia o handshake TLS e informa o host no campo SNI.
- A ferramenta se conecta a esse host por TLS e lê os nomes (CN e SAN) do certificado do servidor.
- Ela cria um certificado com esses nomes e o assina com o seu certificado raiz local (a CA, autoridade certificadora).
- 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 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 (* 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.
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 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 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_insecuredo 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 ou as configurações de proxy no iPhone.
Android. Segundo a documentação da configuração de segurança de rede, 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:
<!-- 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.
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); 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:
"""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, por isso ele nunca aparece aqui:
"""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:
mitmdump --listen-host 127.0.0.1 -p 8080 -s debug_addon.py -w flows.mitmDepois rode o script em um segundo terminal (no PowerShell, defina antes $env:DEBUG_PROXY = "http://127.0.0.1:8080"):
DEBUG_PROXY=http://127.0.0.1:8080 python scraper_debug.py https://httpbin.org/headers https://httpbin.org/status/403A janela do mitmdump imprimiu isto (linhas de conexão removidas):
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). 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 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, as variáveis de ambiente em proxy no wget, a rotação em como rotacionar proxies em Python e a escolha de biblioteca em HTTPX, Requests ou 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:
mitmdump --listen-host 127.0.0.1 --mode upstream:http://pr.proxynet.io:8000 --set upstream_auth=user:pass -s debug_addon.pyTestamos 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 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 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).
Use um Proxies móveis para um IP de operadora ou um Proxies residenciais para uma conexão residencial; o cenário completo está na nossa página de teste de apps.
Para que se usa um proxy MITM?
- Scraper vs navegador: encontre o cabeçalho que transforma
200em403(códigos de status HTTP). - Postman: veja os cabeçalhos finais que o Postman envia (configurações de proxy no Postman).
- O seu próprio app: acompanhe chamadas de API e erros em um celular de teste (teste de apps).
- Cabeçalhos de proxy: identifique
ViaouX-Forwarded-Forem HTTP sem criptografia (níveis de anonimato de proxy). - Um
407: confira se as credenciais chegam ao proxy upstream (métodos de autenticação de proxy). - Verificação de proxies: confirme a saída e as respostas antes de um trabalho (como testar um 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. Aponteverifypara 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
CONNECTcriptografadas e nenhum conteúdo. - Escutar em todas as interfaces. Sem
--listen-host, omitmdumpescutou em0.0.0.0e::no nosso teste; use127.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) |
| 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?.
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). 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.




