
Proxy MITM HTTP/HTTPS basato su Go con intercettazione HTTP/2 e HTTP/1.1, generazione di certificati CA locale/per-host, tunneling CONNECT/WebSocket, caching su disco, pannello di amministrazione, cattura del traffico, politiche di blocco e scansione delle minacce opzionale basata su AI con oscuramento, quarantena e registrazione di audit.
Un proxy HTTP/HTTPS Man‑in‑the‑Middle (MITM) leggero e amichevole per sviluppatori scritto in Go. Supporta HTTP/1.1 e HTTP/2, tunneling CONNECT, tunneling WebSocket (ws/wss), caching delle risposte su disco con filtri flessibili e ricaricamento della configurazione a caldo.

Go MITM Proxy è un proxy di intercettazione progettato per debug, test, apprendimento e intercettazione controllata del traffico HTTP(S). Quando MITM è abilitato, genera dinamicamente certificati foglia per host firmati da una CA locale, consentendo al proxy di decifrare e ispezionare il traffico HTTPS. Può anche funzionare come tunnel TCP trasparente quando MITM è disabilitato o per domini/porte escluse.
Importante: Questa applicazione esegue un'intercettazione Man-in-the-Middle (MITM) attiva, inclusa la generazione e l'uso di certificati TLS per decifrare il traffico HTTPS. A seconda della tua giurisdizione e dell'ambiente di rete, intercettare il traffico senza il consenso chiaro e preventivo di tutti gli utenti interessati potrebbe essere illegale e può violare la privacy, le politiche aziendali o i requisiti normativi.
Prima di utilizzare questo software in qualsiasi ambiente diverso dalla tua macchina locale:
Tutti gli utenti di qualsiasi rete in cui questo proxy potrebbe intercettare il traffico devono essere chiaramente informati che avverrà l'intercettazione e l'ispezione HTTP(S). Il consenso deve essere esplicito e idealmente documentato.
Non eseguire questo software su reti di cui non sei proprietario, che non amministri o per le quali non hai esplicita autorizzazione a testare o monitorare.
Molte regioni hanno leggi severe che regolano l'intercettazione, la registrazione e l'archiviazione dei dati degli utenti (es. GDPR, CCPA, leggi sulle intercettazioni). Sei responsabile di garantire che il tuo utilizzo sia conforme a tutte le normative applicabili.
La chiave privata CA generata (di solito ca-key.pem) consente al detentore di impersonare qualsiasi dominio per gli utenti che fidano del certificato corrispondente.
Questo proxy è progettato per sviluppo, debug, test controllati o scopi educativi — non per monitoraggio occulto o sorveglianza non autorizzata.
Usando questo software, riconosci e accetti la piena responsabilità di garantire che il tuo utilizzo sia lecito, etico e correttamente comunicato a tutti gli utenti interessati.
Prerequisiti:
Clona e compila:
bash
git clone https://github.com/Welfordian/mitm-proxy.git
cd mitm-proxy
go build ./
Questo produce un binario mitm-proxy (o mitm-proxy.exe su Windows) nella directory principale del progetto.
## Avvio Rapido
1) Esegui il proxy con le impostazioni predefinite (ascolta su :8080): ```bash
./mitm-proxy
Al primo avvio, verrà creato un CA locale e salvato in ca-cert.pem e ca-key.pem.
Configura il tuo browser o curl per usare il proxy su http://localhost:8080.
Fida del certificato CA generato (ca-cert.pem) nel tuo sistema operativo/browser per consentire l'intercettazione HTTPS. Vedi Trusting the Local CA.
Visita un sito HTTPS attraverso il proxy e osserva i log. Usa la modalità verbose per maggiori dettagli: ```bash ./mitm-proxy --verbose
## Utilizzo
### Flag della riga di comando
- --config string: Percorso del file config.json
- --listen string: Indirizzo di ascolto (sovrascrive la configurazione)
- --ca-cert string: Percorso del certificato CA esistente (sovrascrive la configurazione)
- --ca-key string: Percorso della chiave CA esistente (sovrascrive la configurazione)
- --mitm bool: Abilita l'intercettazione MITM (default true; impostare false forza il tunneling)
- --verbose bool: Abilita logging verboso
- --watch-config bool: Controlla le modifiche a config.json e applica automaticamente (default true)
- --admin-enabled bool: Abilita API/dashboard di amministrazione locale (default true)
- --admin-addr string: Indirizzo di ascolto API/dashboard amministrazione (default 127.0.0.1:9090)
- --admin-token string: Token bearer di amministrazione (generato all'avvio se omesso)
- --admin-read-token string: Token bearer di sola lettura per accesso amministrativo GET/HEAD/OPTIONS
- --admin-ui bool: Fornisci interfaccia utente amministrativa incorporata (default true)
- --admin-store string: Percorso del database SQLite di amministrazione (default dashboard.db)
I flag CLI sovrascrivono i valori del file di configurazione dove indicato.
### Configurazione (config.json)
Un esempio di config.json è incluso nel repository: ```json
{
"listen_addr": ":8080",
"proxy_name": "MITM-Proxy",
"ca_cert_path": null,
"ca_key_path": null,
"ca_cert_output_path": "ca-cert.pem",
"ca_key_output_path": "ca-key.pem",
"enable_mitm": true,
"admin_enabled": true,
"admin_addr": "127.0.0.1:9090",
"admin_token": "",
"admin_read_token": "",
"admin_ui": true,
"admin_store": "dashboard.db",
"excluded_domains": [],
"blocked_ports": [25, 445, 3389],
"blocked_domains": [],
"blocked_ips": [],
"block_action": "deny",
"block_response_status": 403,
"traffic_capture": {
"store_bodies": false,
"max_body_bytes": 32768,
"redact_bodies": true,
"store_headers": true,
"redacted_headers": ["Authorization", "Cookie", "Proxy-Authorization", "Set-Cookie", "X-Api-Key"],
"store_cookies": true,
"redacted_cookies": []
},
"proxy_auth": {
"enabled": false,
"realm": "MITM Proxy",
"require_auth_for_loopback": false,
"default_action": "allow"
},
"verbose_logging": true,
"log_requests": true,
"max_idle_conns": 200,
"idle_conn_timeout_seconds": 90,
"tls_handshake_timeout_seconds": 10,
"min_tls_version": "1.2",
"tls_next_protos": ["h2", "http/1.1"],
"cache": {
"enabled": true,
"directory": "/var/cache/mitm-proxy",
"include_domains": [],
"exclude_domains": [],
"include_extensions": ["jpg", "png", "webp", "css", "js"],
"exclude_extensions": [],
"ttl": 3600
}
}
Note:
ca_cert_path/ca_key_path non vengono forniti, il proxy scrive una CA generata in ca-cert.pem / ca-key.pem.excluded_domains supporta wildcard (vedi IsDomainExcluded in internal/config).admin_addr predefinito a localhost. Se admin_token è vuoto, viene generato un token per esecuzione e stampato all'avvio.admin_read_token può essere impostato per client dashboard/API di sola lettura.traffic_capture.store_bodies è disabilitato per impostazione predefinita; quando abilitato, i campioni del corpo sono limitati in dimensione e oscurati per impostazione predefinita.traffic_capture.store_headers e controllano se i metadati acquisiti vengono persistenti. oscura interi valori di header, mentre oscura i singoli nomi Cookie e Set-Cookie corrispondenti prima dell'archiviazione.Il server amministrativo serve il pannello all'indirizzo http://127.0.0.1:9090/admin/ per impostazione predefinita. Le rotte API richiedono Authorization: Bearer <token>; per uso locale nel browser, /admin/?token=<token> memorizza il token nell'archivio locale del browser.
La copertura iniziale del pannello/API include:
Il pannello include una conferma di uso responsabile al primo avvio. La chiave privata della CA non viene mai esposta tramite l'API amministrativa.
Lo stato del pannello è memorizzato in SQLite in dashboard.db per impostazione predefinita. Le impostazioni modificate tramite il pannello vengono applicate immediatamente e riscritte nel file JSON configurato, o in config.json quando il proxy è stato avviato con le impostazioni predefinite.
Il frontend amministrativo è un'app Vite/React in internal/admin/ui. La sua build di produzione viene emessa in internal/admin/ui/dist e incorporata nel binario Go. Per aggiornare gli asset del pannello:```bash
cd internal/admin/ui
npm install
npm run build
### Proxy a Monte a Catena
Il traffico in uscita può essere incatenato attraverso un proxy upstream HTTP o HTTPS, come Burp, ZAP o un proxy di uscita aziendale. Quando abilitato, il normale inoltro HTTP(S), i tunnel pass-through CONNECT, WebSockets e gli invii di Repeater utilizzano il proxy upstream a meno che un host non corrisponda a `no_proxy`.```json
{
"upstream_proxy": {
"enabled": true,
"url": "http://127.0.0.1:8080",
"username": "",
"password_env": "UPSTREAM_PROXY_PASSWORD",
"no_proxy": ["localhost", "127.0.0.1", "*.internal"],
"chain_tunnels": true,
"apply_to_repeater": true
}
}
In v1 sono supportati solo URL proxy upstream http:// e https://. Se è necessaria l'autenticazione Basic, impostare username e fornire la password tramite la variabile d'ambiente indicata; le credenziali incorporate nell'URL vengono rifiutate e non vengono mai mostrate nelle impostazioni della dashboard. Se il proxy upstream è abilitato ma non disponibile, le richieste interessate falliscono visibilmente invece di ricorrere silenziosamente a connessioni dirette.
La vista Access Control della dashboard gestisce gli utenti proxy client e le regole ACL allow/deny ordinate. Gli utenti proxy sono memorizzati in SQLite con hash bcrypt delle password; le password in chiaro sono accettate solo durante la creazione o il reset di un utente e non vengono mai restituite dall'API.
Abilita l'autenticazione Basic del proxy tramite proxy_auth in config.json o nella vista Impostazioni. Quando abilitato, i client devono inviare Proxy-Authorization: Basic ... a meno che i client loopback non siano esenti. Le regole ACL vengono valutate per priorità e possono corrispondere a nome utente, IP/CIDR di origine, host o host wildcard, porta o intervallo di porte, metodo e ambito di ricerca. Liste di corrispondenza vuote significano 'qualsiasi'.
Proxy-Authorization viene rimosso prima dell'inoltro, concatenamento upstream, cattura del traffico, ricerca nella cache, scansione delle minacce e clonazione Repeater. Il traffico catturato include l'attribuzione proxy_user quando disponibile, e la casella di ricerca Traffic può corrispondere ai nomi utente proxy.
La vista Repeater della dashboard consente ai ricercatori di sicurezza di clonare il traffico HTTP catturato in casi modificabili salvati. Un caso memorizza il metodo, l'URL, le intestazioni, un campione del corpo, il timeout e un ID opzionale del flusso di traffico di origine. Ogni invio memorizza un'esecuzione con stato, durata, intestazioni di risposta, un campione del corpo della risposta limitato e eventuali errori upstream.
I corpi delle richieste catturate vengono precompilati solo se traffic_capture.store_bodies era abilitato al momento della cattura. Se era abilitata la redazione del corpo, il ripetitore riceve il campione redatto; i corpi non catturati rimangono vuoti e possono essere modificati manualmente.
L'endpoint legacy POST /api/traffic/{id}/replay rimane disponibile per il replay singolo, mentre il ripetitore è pensato per la mutazione ripetibile delle richieste e il confronto delle risposte.
La vista Pentest Toolkit della dashboard costruisce mappe passive dei target dal traffico catturato. Ricostruire una mappa analizza solo il traffico memorizzato per l'ambito selezionato, raggruppa gli endpoint per percorso normalizzato, estrae parametri da query/corpo/cookie/intestazioni, registra parametri riflessi e interessanti, e aggiunge suggerimenti passivi come intestazioni di sicurezza mancanti, lacune negli attributi dei cookie, CORS permissivi ed errori verbosi.
Le mappe di Pentest sono persistite in SQLite e possono essere cancellate indipendentemente. Il toolkit non invia mai richieste, non esegue crawling, fuzzing o mutazioni dei target; le evidenze degli endpoint possono essere clonate in Repeater per test manuali.
La vista Scopes della dashboard consente ai ricercatori di definire confini di target denominati con host, sottostringa URL e pattern di metodo opzionali. Gli ambiti abilitati vengono abbinati automaticamente quando il traffico viene catturato; i flussi corrispondenti, i casi Repeater clonati e gli eventi dello scanner di minacce ricevono un singolo scope_id.
Il selettore globale dell'ambito filtra le viste Traffic, Repeater e Threat Scanner attraverso tutto il traffico, un ambito abilitato selezionato o elementi fuori ambito. Eliminare un ambito cancella i valori scope_id correlati senza eliminare il traffico catturato, i casi Repeater, le esecuzioni o i dati delle minacce.
I filtri per ambito sono disponibili su GET /api/traffic, GET /api/repeater/cases e GET /api/threats/events con scope_id=<id> o scope_id=__out_of_scope__. Aggiungere include_out_of_scope=true per includere le righe non assegnate accanto a un ambito selezionato.
La vista AI Copilot della dashboard memorizza note di ricerca generate dall'IA collegate a Traffic, casi Repeater, esecuzioni, ambiti o eventi di minaccia. Il dettaglio del traffico può chiedere al copilota di spiegare una richiesta o suggerire i prossimi test manuali; Repeater può suggerire test per un caso salvato o confrontare le ultime due esecuzioni.
Il copilota è solo consultivo. Non invia mai traffico, non modifica casi Repeater, non cambia ambiti, non modifica impostazioni e non cancella dati. Il traffico fuori ambito può essere spiegato, ma i suggerimenti di test attivi vengono intenzionalmente omessi.
Abilitalo tramite ai_copilot in config.json o nella vista Impostazioni:```json
{
"ai_copilot": {
"enabled": true,
"provider": "openai",
"model": "gpt-5.4-nano",
"timeout_ms": 10000,
"max_body_bytes": 32768,
"redact_before_ai": true,
"openai_api_key_env": "OPENAI_API_KEY"
}
}
The OpenAI API key is read from the configured environment variable and is not stored in the dashboard or config file. Sensitive headers, body samples, and query values are redacted before AI context is sent when `redact_before_ai` is enabled. Saved notes include the model, prompt hash, summary, and structured AI output, not the full prompt.
### Scansione delle Minacce AI
Il threat scanner può ispezionare le richieste e risposte HTTP con euristiche locali e, quando configurato, chiedere a OpenAI un secondo parere prima di bloccare il traffico sospetto.
1. Crea una chiave API di OpenAI ed esponila al processo proxy:```powershell
$env:OPENAI_API_KEY = "sk-..."
Su macOS/Linux:```bash export OPENAI_API_KEY="sk-..."
2. Abilita lo scanner in `config.json`:```json
{
"threat_scanner": {
"enabled": true,
"mode": "suspicious_only",
"provider": "openai",
"model": "gpt-5.4-nano",
"second_opinion_model": "gpt-5.4-mini",
"scan_requests": true,
"scan_responses": true,
"max_body_bytes": 131072,
"max_ai_body_bytes": 32768,
"ai_timeout_ms": 750,
"block_threshold": 0.85,
"warn_threshold": 0.65,
"require_ai_confirmation_for_block": true,
"block_critical_local_on_ai_failure": true,
"fail_open": true,
"scan_content_types": [
"text/html",
"text/plain",
"application/json",
"application/javascript",
"text/javascript",
"application/xml"
],
"skip_content_types": [
"image/",
"video/",
"audio/",
"font/",
"application/octet-stream"
],
"trusted_domains": [
"accounts.google.com",
"login.microsoftonline.com",
"github.com"
],
"allowlist_domains": [],
"malicious_domains": [],
"malicious_file_hashes": [],
"threat_intel_updated": "",
"quarantine_dir": "quarantine",
"debug_log_path": "threats.log",
"redact_before_ai": true,
"store_bodies": false,
"openai_api_key_env": "OPENAI_API_KEY"
}
}
La vista **Threat Scanner** della dashboard mostra conteggi di richieste/risposte scansionate, conteggi di chiamate AI, rilevamenti, dettagli del verdetto, prime regole locali e azioni di override.
Modalità scanner:
- `suspicious_only`: predefinita; le euristiche locali decidono quando chiamare l'AI.
- `all_text`: chiama l'AI per traffico simile a testo.
- `paranoid`: chiama anch'essa l'AI per traffico simile a testo ed è pensata per test ad alta sensibilità.
- `metadata_only`: utilizza header, URL, host e metadati senza revisione del corpo da parte dell'AI.
- `off`: disabilita la scansione.
Controlli utili per sicurezza e privacy:
- `redact_before_ai`: oscura segreti comuni e dati personali prima di inviare le evidenze a OpenAI.
- `max_ai_body_bytes`: limita il campione di corpo incluso nelle evidenze AI.
- `require_ai_confirmation_for_block`: impedisce alle euristiche locali di bloccare a meno che l'AI non confermi, tranne quando `block_critical_local_on_ai_failure` è abilitato per evidenze locali critiche.
- `fail_open`: consente il traffico quando lo scanner fallisce, a meno che non siano attive impostazioni di blocco più rigorose.
- `trusted_domains` e `allowlist_domains`: riducono i falsi positivi per host noti come sicuri.
- `malicious_domains` e `malicious_file_hashes`: aggiungono colpi di intelligence sulle minacce locali senza attendere l'AI.
- `debug_log_path`: scrive le decisioni dello scanner in un log locale in formato JSONL per il debug.
Per utilizzare un nome di variabile d'ambiente diverso per la chiave API, imposta `openai_api_key_env` ed esporta quella variabile prima di avviare il proxy. Non inserire le chiavi API direttamente in `config.json`.
### Fiducia del CA Locale
Per intercettare HTTPS, importa e approva ca-cert.pem nel tuo sistema operativo/browser:
- macOS: Accesso Portachiavi → login/sistema → Certificati → importa ca-cert.pem → imposta Sempre Fidati.
- Windows: certmgr.msc → Autorità di Certificazione Radice Attendibili → Certificati → importa ca-cert.pem.
- Linux (varia): es., update-ca-certificates, o archivio specifico del browser (Firefox: Impostazioni → Privacy e Sicurezza → Certificati → Visualizza → Autorità → Importa).
Senza approvare il CA, i browser mostreranno avvisi di certificato per i siti intercettati.
### Utilizzo del Proxy
Imposta il tuo proxy HTTP/HTTPS sull'indirizzo di ascolto (predefinito http://localhost:8080).
Esempi con curl: ```bash
# HTTP
curl -x http://localhost:8080 http://example.com/
# HTTPS (after trusting the CA for full MITM)
curl -x http://localhost:8080 https://example.com/
# Disable MITM and tunnel only
./mitm-proxy --mitm=false
# Change listen address
./mitm-proxy --listen=127.0.0.1:9090
Note su WebSocket:
La cache è basata su file e considera solo le richieste HTTP GET quando abilitata. La selezione è controllata da:
In caso di hit nella cache, le risposte includono:
La directory della cache è garantita all'avvio e alle modifiche della configurazione. Se non è impostata alcuna directory, il valore predefinito è ./cache.
go build ./ ./mitm-proxy --config ./config.json
Il server si collega al listen_addr configurato e gestisce HTTP + HTTPS con ALPN.
## Roadmap
- Autenticazione proxy (Basic/NTLM) e ACL
- Supporto per proxy a monte/chaining
- Generazione di file PAC e script helper
- Interfaccia utente per ispezionare flussi e voci della cache
- Controlli di fingerprinting TLS e stile JA3
- Endpoint metriche/health e integrazione Prometheus
## Contribuire
Issue e pull request sono benvenuti. Per modifiche significative, si prega di aprire prima un issue per discutere ambito e progettazione.
Stile di codifica: mantenere le modifiche minime e mirate; preferire chiarezza e funzioni piccole e componibili.
traffic_capture.store_cookiesredacted_headersredacted_cookiesproxy_auth abilita l'autenticazione Basic del proxy client basata su utenti gestiti da SQLite e regole ACL ordinate.blocked_domains supporta nomi esatti e pattern wildcard come *.example.com; blocked_ips supporta singoli IP e range CIDR.cache.include_domains e cache.exclude_domains sono mutuamente esclusivi, lo stesso per include_extensions vs exclude_extensions.--config o il predefinito ./config.json e applica le modifiche a caldo tramite Proxy.SetConfig.