iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

MITM (Lab Only)

Man-in-the-middle (MITM) testing in an authorised engagement intercepts traffic between an app and a server to evaluate TLS configuration, certificate pinning, content integrity, and what data leaves the device. The right scope is "evaluate the controls"; the wrong scope is "watch real users" — keep the engagement on devices and accounts you own, with prior written approval.

Authorised MITM workflow with mitmproxy

EXAMPLE
# ===== 1) Rules of engagement (excerpt — signed before any run) =====
# Targets:      a test device (yours), staging / lab backends only
# Off-limits:   production hosts, traffic from anyone except the tester
# Window:       2026-06-18 09:00-17:00 AEST
# Storage:      flow files encrypted at rest; deleted within 7 days
# Reporting:    consolidated report within 5 business days
# PoC policy:   demonstrate the FINDING with minimum data; never pivot

# ===== 2) Why MITM, defensively =====
# It answers questions your unit tests cannot:
# - Is TLS actually negotiated with strong ciphers?
# - Does the app pin the certificate (or fail open)?
# - Are sensitive headers (Authorization, cookies) really only over TLS?
# - Does the app upgrade-insecure-requests as designed?
# - Are the platform APIs the app uses actually behind HTTPS?

# ===== 3) Lab setup (one-time) =====
# A) Tester laptop (where mitmproxy runs)
pip install mitmproxy   # CLI: mitmproxy / mitmweb / mitmdump

# B) Test device (your phone) on the same Wi-Fi as the laptop
# Settings -> Wi-Fi -> the network -> Proxy -> Manual -> laptop IP + port 8080

# C) Install the mitmproxy CA cert on the TEST DEVICE only
# Browse on the device to http://mitm.it -> follow the per-OS instructions.
# DO NOT install it on coworkers' devices. NEVER on production fleet.

# ===== 4) Run mitmproxy =====
mitmweb --listen-port 8080 --set web_host=127.0.0.1
# OR for CLI / scripted runs
mitmdump -w session.flows --listen-port 8080

# Now traffic from the test device flows through the proxy. The web UI lets you
# drill into headers, body, JSON, response codes, latencies.

# ===== 5) Defensive checks you should run =====

# A) TLS version + cipher
# In mitmweb, click any flow -> 'TLS' tab. Reject if < TLS 1.2 or RC4/3DES seen.

# B) Certificate pinning
# Install the mitm CA on the test device, then run the app.
# - App rejects the connection -> pinning works ✅
# - App connects -> pinning is missing or broken ❌
# Report: severity High; recommend OkHttp CertificatePinner / iOS pinning.

# C) Token / cookie scope
# Filter: 'Authorization' OR 'Set-Cookie'. Verify:
#   - sent only to expected hosts
#   - HttpOnly + Secure + SameSite on session cookies
#   - JWTs include exp + aud; no PII in claims

# D) Mixed content / cleartext fallback
# Try to MITM with no TLS (force the app onto plain HTTP). The app should
# refuse. If it falls back to HTTP, that is a finding.

# E) Sensitive fields in URLs
# Filter for 'email=' / 'phone=' / 'password=' in query strings. URL params
# leak via Referer headers and access logs.

# ===== 6) What MITM testing should NEVER look like =====
# - Watching anyone else's traffic
# - Installing CA certs on devices you do not own
# - Bypassing pinning on production apps you don't have authorisation for
# - Storing or sharing intercepted payloads beyond minimum evidence
# - Persisting the proxy after the engagement window

# ===== 7) Reporting template =====
cat <<'EOF'
## Finding: TLS allows downgrade to TLS 1.0
Severity:  High (cipher integrity, regulatory non-compliance)
Scope:     api.lab.example.test (staging)
Evidence:  flow #2147 in session.flows; TLS handshake shows ClientHello
           with TLS 1.0 supported and accepted by the server.
Fix:       Configure the load balancer / TLS terminator to require TLS 1.2+.
           Disable AES-CBC ciphers in favour of AES-GCM and ChaCha20-Poly1305.
           Verify with: testssl.sh api.lab.example.test
EOF

# ===== 8) Cleanup after the engagement =====
# - Remove the mitm CA from the test device
# - Delete .flows files from disk after writing them into the report archive
# - Encrypt the archive (gpg) and share over the client's secure channel
# - Confirm in writing that no data was retained outside the agreed archive

Why it matters

MITM testing earns trust by what it does NOT touch. Stay on devices and accounts you own, get permission in writing for the network and backends in scope, redact evidence to the minimum that proves the finding, and delete the rest. The credibility of a security engagement is built on the discipline of "we only watched what we were told to watch".

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
# Demonstrate MitM ONLY in a lab you own.
# Tools (lab only): mitmproxy, bettercap.
# The lesson: any HTTP traffic between you and a server you don't trust
# can be inspected and modified. Therefore HTTPS everywhere, HSTS preload,
# and certificate pinning on mobile.
Try it Yourself »

Discussion

Loading…