UP | HOME

Proxying HTTPS

Table of Contents

Rambling about making an HTTP proxy for debugging and security testing.

Networking

The first objective if you decide to make such a tool, is build a server that you can point your browser at and will forward messages to their destination, while recording the info.

First attempt

A basic HTTP proxy is trivial to write, if you aren't concerned with preserving the literal message, you can simply glue existing server and client together.

My first attempt I tried this using Hunchentoot as a server and Dexador as a client.

This is not a very good strategy, as it gives no guarantee that the message you send is the same as the one you recieved. These things might not be preserved, for example:

  • Header order
  • Whitespace
  • Case

You will also have to do a lot of work to smooth out the differential between the server and client.

Second attempt

Create an HTTP reader and writer that preserves raw messages.

I used http for reading and writing HTTP messages, as well as providing a basic multithreaded TCP server. This works better for my intended goal but it is not easy to completely implement a reader for messages.

Issues arise when encodings are used (see Accept-Encoding header) as a normal char stream cannot handle everything it might recieve. I have yet to solve this but I believe the solution is to use a binary stream and the functions provided by chunga to read from it. For now I am working around this issue by stripping the `Accept-Encoding` header from requests before forwarding them.

Other issues I forsee will be the completeness of my HTTP reader when handling different types of messages where the body size is not determined by the normal `Content-Length` header.

Future attempt

If my second strategy doesn't work out, I will probably decide to modify existing HTTP libraries to preserve raw messages. fast-http by Fukamachi seems like a good candidate as long as I am comfortable with part of the program being in C.

Issues

I need to be able to handle SSL messages, since in practical use, almost every message is encrypted. This should not add much complexity to the program but I need to figure out how to properly handle the HTTP `Connect` method.

User interface

One of the biggest challenges of making a popular app is having a good UI. This is challenging because UI design seems to be a conflict between mass appeal and efficiency.

My preference

The optimal UI, (in my opinion), is Emacs-style, where every aspect of the program is introspectable and modifiable to the user. Commands are defined and then bound to keys for the user to invoke.

Popular preference

In contrast, most popular apps right now are QT/GTK/React apps where actions are done by clicking and navigating menus. I believe this is very slow and inefficient if you already know what you want to accomplish, but it is a good interface for exploring new things and being able to see some of what is available to use.

Comprimise

The solution to this conflict would be to build the program Emacs-style, and then create an optional facade to give users who want it a "clicky" interface.

First attempt

For now, I am going to write the UI as a Lem "plugin". Lem has all the functionality for Emacs-style interfaces built-in, and since it is an interactive Lisp program, I can run the proxy server directly in Lem.

Emacs 30.2 (Org mode 9.7.11)