cloudflare / mitmengine

A MITM (monster-in-the-middle) detection tool. Used to build MALCOLM:
https://malcolm.cloudflare.com
BSD 3-Clause "New" or "Revised" License
799 stars 68 forks source link

Add Processor.CheckRequest for webserver integration & demo & tests #22

Open jeyrey opened 4 years ago

jeyrey commented 4 years ago

This PR resolves #21 by adding the new function Processor.CheckRequest(*tls.ClientHelloInfo,*http.Request) as a wrapper around the functionality of Processor.Check() along with updates to documentation, tests, and a demo to show webserver developers how they could use mitmengine to get reports on incoming traffic. It addresses the use-case mentioned by Matt Holt of Caddy in this issue.

The largest unexpected design challenge faced was the fact that the crypto/tls.ClientHelloInfo structure does not expose which TLS extensions were in use in the actual client hello. These extension sets are part of normal signatures parsed under the original design. The presence of five extensions could be inferred from the availability of fields in crypto/tls.ClientHelloInfo, but dozens more are not visible. This causes matching failures.

In consultation with Luke, I decided to modify the signature matching logic to ignore TLS extensions when using CheckReport(). To keep the original API intact, I made both Check() and CheckReport() into wrappers around the original check() functionality with an added flag to allow CheckReport() to have TLS extension mismatches ignored. This allowed for minimal changes to existing functionality. This also meant that when testing that Check() and CheckReport() generate consistent responses for all sample traffic I needed to write extra logic to account for the difference of available inputs to each.

The result is that we can use the extensive existing reference set of signatures while ignoring TLS extensions that are not visible to CheckRequest(). This is a trade-off to make an easier-to-use API for webserver developers at the cost of some accuracy. This trade-off is documented so developers can make an informed selection.

Other Design Choices

Where to find changes:

Tests

I added tests to ensure new features are working as intended and to alert in the future if they stop working.

Demo

I created a demo at cmd/webserver_integration_demo/main.go. Instructions to generate a cert and run the HTTPS server demo are in README.md. Then you can fetch https://localhost:8443 with any client (optionally with MITM) and see the mitmengine report returned rendered semi-nicely in HTML.

Sources Used

Luke asked me to cite my sources. This is not every page I looked at, but these were the most helpful:

About TLS

Preserving ClientHelloInfo after handshake in a HTTPS Server:

Messaging in golang tests

Etiquette in open-source PRs:

User-Agents and headers

Misc