Interactive HTTPS proxy for API security testing with traffic interception, modification, and replay capabilities. Supports HTTP/1, HTTP/2, HTTP/3, WebSockets, and TLS-protected protocols...
mitmproxy is an interactive, TLS-capable intercepting HTTP proxy for penetration testers and developers. It enables real-time inspection, modification, and replay of HTTP/HTTPS traffic including APIs, mobile apps, and thick clients. With support for HTTP/1, HTTP/2, HTTP/3, and WebSockets, mitmproxy provides comprehensive coverage for modern API security testing.
mitmproxy - Interactive console interface with keyboard navigation mitmweb - Web-based GUI for visual traffic inspection mitmdump - Command-line tool for automated traffic capture and scripting
Install and run mitmproxy:
# Install via pip
pip install mitmproxy
# Start interactive console proxy
mitmproxy
# Start web interface (default: http://127.0.0.1:8081)
mitmweb
# Start command-line proxy with output
mitmdump -w traffic.flow
Configure client to use proxy (default: localhost:8080)
For manual API security testing and analysis:
# Console interface
mitmproxy --mode regular --listen-host 0.0.0.0 --listen-port 8080
# Or web interface
mitmweb --mode regular --listen-host 0.0.0.0 --listen-port 8080
Progress: [ ] 1. Install mitmproxy CA certificate on mobile device [ ] 2. Configure device WiFi to use mitmproxy as proxy [ ] 3. Start mitmweb for visual traffic inspection [ ] 4. Launch mobile app and exercise all features [ ] 5. Review API endpoints, authentication mechanisms, data flows [ ] 6. Test for common API vulnerabilities (OWASP API Top 10) [ ] 7. Export traffic as HAR for further analysis [ ] 8. Document findings with request/response examples
Work through each step systematically. Check off completed items.
For capturing and analyzing API traffic at scale:
mitmdump -w api-traffic.flow --mode regular
# Replay to server
mitmdump -nc -r api-traffic.flow
# Replay with modifications via script
mitmdump -s replay-script.py -r api-traffic.flow
# Using Python API
python3 -c "from mitmproxy.io import FlowReader; from mitmproxy.tools.dump import DumpMaster;
import sys; [print(flow.request.url) for flow in FlowReader(open('api-traffic.flow', 'rb')).stream()]"
For automated security testing with custom logic:
api-test.py):from mitmproxy import http
class APISecurityTester:
def request(self, flow: http.HTTPFlow) -> None:
# Modify requests on-the-fly
if "api.example.com" in flow.request.pretty_url:
# Test for authorization bypass
flow.request.headers["X-User-ID"] = "1"
def response(self, flow: http.HTTPFlow) -> None:
# Analyze responses
if flow.response.status_code == 200:
if "admin" in flow.response.text:
print(f"[!] Potential privilege escalation: {flow.request.url}")
addons = [APISecurityTester()]
mitmproxy -s api-test.py
# Or for automation
mitmdump -s api-test.py -w results.flow
For testing mobile apps with certificate pinning:
mitmproxy --mode reverse:https://api.example.com --listen-host 0.0.0.0 --listen-port 443
mitmproxy supports multiple deployment modes:
Regular Proxy Mode (default):
mitmproxy --mode regular --listen-port 8080
Client configures proxy settings explicitly.
Transparent Proxy Mode (invisible to client):
mitmproxy --mode transparent --listen-port 8080
Requires iptables/pf rules to redirect traffic.
Reverse Proxy Mode (sits in front of server):
mitmproxy --mode reverse:https://api.example.com --listen-port 443
mitmproxy acts as the server endpoint.
Upstream Proxy Mode (chain proxies):
mitmproxy --mode upstream:http://corporate-proxy:8080
Routes traffic through another proxy.
Install mitmproxy CA certificate for HTTPS interception:
Browser/Desktop:
Android:
adb push ~/.mitmproxy/mitmproxy-ca-cert.cer /sdcard/iOS:
Test authentication mechanisms and token handling:
# auth-test.py
from mitmproxy import http
class AuthTester:
def __init__(self):
self.tokens = []
def request(self, flow: http.HTTPFlow):
# Capture auth tokens
if "authorization" in flow.request.headers:
token = flow.request.headers["authorization"]
if token not in self.tokens:
self.tokens.append(token)
print(f"[+] Captured token: {token[:20]}...")
# Test for missing authentication
if "api.example.com" in flow.request.url:
flow.request.headers.pop("authorization", None)
print(f"[*] Testing unauthenticated: {flow.request.path}")
addons = [AuthTester()]
Fuzz API parameters for injection vulnerabilities:
# fuzz-params.py
from mitmproxy import http
class ParamFuzzer:
def request(self, flow: http.HTTPFlow):
if flow.request.method == "POST" and "api.example.com" in flow.request.url:
# Clone and modify request
original_body = flow.request.text
payloads = ["' OR '1'='1", "<script>alert(1)</script>", "../../../etc/passwd"]
for payload in payloads:
# Modify parameters and test
# (Implementation depends on content-type)
print(f"[*] Testing payload: {payload}")
addons = [ParamFuzzer()]
Inspect and test GraphQL APIs:
# graphql-test.py
from mitmproxy import http
import json
class GraphQLTester:
def request(self, flow: http.HTTPFlow):
if "/graphql" in flow.request.path:
try:
data = json.loads(flow.request.text)
query = data.get("query", "")
print(f"[+] GraphQL Query:\n{query}")
# Test for introspection
if "__schema" not in query:
introspection = {"query": "{__schema{types{name}}}"}
print(f"[*] Testing introspection")
except:
pass
addons = [GraphQLTester()]
Export traffic as HTTP Archive for analysis:
# Export flows to HAR format
mitmdump -s export-har.py -r captured-traffic.flow
# export-har.py
from mitmproxy import http, ctx
import json
class HARExporter:
def done(self):
har_entries = []
# Build HAR structure
# (Simplified - use mitmproxy's built-in HAR addon)
ctx.log.info(f"Exported {len(har_entries)} entries")
addons = [HARExporter()]
Or use built-in addon:
mitmdump --set hardump=./traffic.har
Run automated API security tests:
# Run mitmdump with test script in CI
mitmdump -s api-security-tests.py --anticache -w test-results.flow &
PROXY_PID=$!
# Run API tests through proxy
export HTTP_PROXY=http://localhost:8080
export HTTPS_PROXY=http://localhost:8080
pytest tests/api_tests.py
# Stop proxy and analyze results
kill $PROXY_PID
python3 analyze-results.py test-results.flow
Standard workflow for iOS/Android apps:
Filter displayed traffic by expression:
# Show only API calls
mitmproxy --view-filter '~d api.example.com'
# Show only POST requests
mitmproxy --view-filter '~m POST'
# Show responses with specific status
mitmproxy --view-filter '~c 401'
# Combine filters
mitmproxy --view-filter '~d api.example.com & ~m POST'
Modify traffic using built-in mappers:
# Replace request headers
mitmproxy --modify-headers '/~u example/Authorization/Bearer fake-token'
# Replace response body
mitmproxy --modify-body '/~s & ~b "error"/success'
Intercept and modify WebSocket traffic:
# websocket-test.py
from mitmproxy import websocket
class WebSocketTester:
def websocket_message(self, flow):
message = flow.messages[-1]
print(f"[+] WebSocket: {message.content[:100]}")
# Modify messages
if message.from_client:
message.content = message.content.replace(b"user", b"admin")
addons = [WebSocketTester()]
Solution: Ensure mitmproxy CA certificate is properly installed and trusted:
# Verify certificate location
ls ~/.mitmproxy/
# Regenerate certificates if needed
rm -rf ~/.mitmproxy/
mitmproxy # Regenerates on startup
Solution:
Solution: Use SSL unpinning tools:
# Android with Frida
frida -U -l universal-android-ssl-pinning-bypass.js -f com.example.app
# Or modify app to disable pinning (development builds)
Solution: mitmproxy supports HTTP/2 by default. For HTTP/3:
# Enable HTTP/3 support (experimental)
mitmproxy --set http3=true
Use mitmproxy to test for OWASP API Security Top 10 vulnerabilities: