A simple reverse proxy in Python

Michael Mollard
Dec 19, 2018 · 4 min read
Image for post
Image for post

In this article, I’ll talk you though how I created a reverse proxy in python able to inject security headers to solve one of our data issue that we had on one project.

I work in a corporate environment that strongly promote separation of the different development environnements.
This is without a doubt a good practice in theory. However, what ended up happening is that our pre-production environment had a lot of incoherent tests setup across our 20 or so external services.Next to that, in our staging environment we were struggling to find even one test set that would allows us to run any requests completely.

Seeing that, I decided to:

  • Dump my preproduction data and load it in staging
  • Create a bridge between environment capable of authenticating itself.
  • Send all the external call devoid of side effect through this bridge

You can check out the final result on GitHub or follow the rest of this article to learn more about the building process.

Why Python ?

There are many reasons why I went for python as my choice language for the implementation. Excluding the fact that it’s syntax is arguably one of the easiest to understand, here are some of the reasons:

  • It’s present on most “modern” servers
  • It comes with a package manager (PIP)
  • Integrate well with virtual environment that can be installed with user permission
  • You don’t need root access to the server

But wait! What is a reverse proxy ?

If you’re not familiar with the concept you could read the Wikipedia page on the subject. Basically, a reverse proxy is a server that sit between you and the real destination of your request. It will query the real ressource you want to access for you and give you back the response it got after having tampered with it.

In a way it acts as a man in the middle if you are familiar with the concept.

Here is a schema of what we’re going to build.

Image for post
Image for post

The reverse proxy

The requirements

The reverse proxy we’re trying to build will have the following characteristics:

  • Listen to incoming requests
  • Change the target host name to the real target
  • Inject headers
  • Send the requests
  • Transmit the response as is

Understanding HTTP requests

Even if not necessary, a good understanding of the HTTP protocol can help you understand the inner workings of the tools we’re using.

In it’s simplest form an HTTP request will look like that.

What we aim to do is the change the HOST header and add a new line with the security header (e.g Authorization: Bearer token)

But the HTTP protocol allows for much more complexity with chunked and or zipped requests and response.

Let’s make thing easier with Web Servers.

Let’s start by building a Web Server that will listen to incoming requests. Luckily Python comes with a Web Server implementation that’s quite straightforward to user.

With this we have fulfilled the first of our requirements, that is, we have a reverse proxy that is listening to incoming requests.

Injecting Headers

In the previous I did not show the function in charge of parsing the request header. This is where the magic of header injection will happen. Indeed the requests header are going to be used and sent to the real target so this is the perfect place to inject any complementary headers.

Once the headers are parse using the syntax, injecting headers becomes as easy as adding a new value in a dictionary.

Sending the request to the real target

All that’s left now that we have a request with some additional headers is to send it to our desired target. For that I’m going to use a really powerful library that was made to handle HTTP requests called requests.

You can install it by running in your favorite terminal.

Once that’s done, the following bit of code is all that’s needed to send the modified request.

Again you can check the final version on my GitHub

Now what ?

Well I guess that you can let your imagination bring you where you need to be but if you need some hint here are some of the things you can use such a custom reverse proxy for:

  • Adding CORS to connect to a backend that doesn’t provide them directly
  • Injecting secret hidden from your front

Originally published at sipios.com.

Sipios

Sipios conceives and develops tailored products in record…

Michael Mollard

Written by

Architect developer. I love understanding how things work

Sipios

Sipios

Sipios conceives and develops tailored products in record time that shape tomorrow’s financial industry. We take on our clients’ most exciting technical and business challenges which we share in our publications.

Michael Mollard

Written by

Architect developer. I love understanding how things work

Sipios

Sipios

Sipios conceives and develops tailored products in record time that shape tomorrow’s financial industry. We take on our clients’ most exciting technical and business challenges which we share in our publications.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store