diff options
| author | srdusr <[email protected]> | 2026-06-16 22:57:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2026-06-16 22:57:00 +0200 |
| commit | 23c8ab359c2108654d57176e233d2c099b398f31 (patch) | |
| tree | 3e2d1c66d987b4b771da69e67bd8a0c9ad2fc3db /PLAN.md | |
| parent | 6114567258bcad0517a0d881168711aaacdba5d5 (diff) | |
| download | mitmux-23c8ab359c2108654d57176e233d2c099b398f31.tar.gz mitmux-23c8ab359c2108654d57176e233d2c099b398f31.zip | |
Client (mutual-TLS) certificates
Adds internal/clientcert: a cert/key pair matched to hosts by the same
substring-or-regex pattern model as scope.Rule, so mitmux can present
a client certificate on an upstream TLS handshake that requires one -
the previous behavior was a hard handshake failure with no way to
authenticate. Wired into both places mitmux dials an https:// upstream
over its own TLS client connection: proxy.go's handleConnect (live
proxied traffic) and repeat.go's dialForRepeat (Repeater/Intruder
resends), both through a new Server.clientCertFor(host) helper.
Stored in a new client_certs table, mirroring the existing scope_rules
persistence pattern. The TUI (`t` from history) is add-only like
scope, for the same reason: delete and re-add covers changing
anything, and it's a rarely-touched, low-cardinality list. The add
form takes cert/key file paths and reads them once at save time - PEM
content, not the path, is what's stored and later presented, so a
cert keeps working even if the original file moves afterward.
Verified live against a real mutual-TLS-requiring origin server:
without a matching cert the handshake correctly fails; with one
configured, the origin receives it and the request succeeds; toggling
it off reproduces the failure, confirming the enable/disable path
works end to end.
Diffstat (limited to 'PLAN.md')
| -rw-r--r-- | PLAN.md | 21 |
1 files changed, 19 insertions, 2 deletions
@@ -384,8 +384,25 @@ This closes every item from the expanded "worth considering" list. Skipped deliberately (from the research, matches this tool's stated scope): active/passive vulnerability scanning, plugin marketplace, -Collaborator/OAST, team collaboration, CI integration, client TLS -(mutual-TLS) certs, invisible/non-proxy-aware proxying. +Collaborator/OAST, team collaboration, CI integration, +invisible/non-proxy-aware proxying. Client (mutual-TLS) certificates +were later added - see below. + +## Client (mutual-TLS) certificates + +internal/clientcert stores cert/key pairs matched to hosts by the same +substring-or-regex pattern model as scope.Rule (internal/scope) - one +consistent mental model across every "which rule applies to this +host" decision in the tool. A match is looked up in proxy.go's +handleConnect (live proxied HTTPS) and repeat.go's dialForRepeat +(Repeater/Intruder resends), both funneling through +Server.clientCertFor, and passed into the outbound tls.Config's +Certificates field when non-nil. Deliberately add-only in the TUI, no +edit-in-place, same reasoning as scope: delete and re-add covers +changing anything, and it's a rarely-touched, low-cardinality list. +The TUI form takes file paths and reads them once at save time - the +PEM content itself, not the path, is what's stored, so a cert keeps +working even if the original file later moves. ## Licensing, packaging, and browser/mobile support |