3

I was wondering if there was any way to re-order HTTP headers that are being sent by our browser, before getting sent back to the web server?

Since the order of the headers leaves some kind of "fingerprinting", see this post and this post, I was thinking about using MITMProxy (with Inline Scripting, I guess) to modify headers on-the-fly. Is this possible?

How would one achieve that?
Note: I'm looking for a method that could be scripted, not a method using a graphical tool like the Burp Suite (although Burp is known to be able to re-order headers)

I'm open to suggestions. Perhaps NGINX might come to the rescue as well?

EDIT: I should be more specific, by giving an example...

Let's say I'm using Firefox. With the use of a funky add-on, I'm spoofing my user-agent to "look" like a Chrome browser. But then if I test my browser with ip-check.info, the "signature" of my browser remains the one of Firefox, even though my spoofed user-agent shows "Chrome".

So the solution, in this specific case, should be to re-order the HTTP headers in the same manner as Chrome does.

How can this be done?

Community
  • 1
  • 1
Tux
  • 51
  • 6

1 Answers1

0

For the record, the order of the HTTP headers should not matter at all according to RFC 7230. But now that you have asked... this can be done in mitmproxy as follows:

import random

def request(context, flow):
    # flow.request.headers.fields is a tuple of (name, value) header tuples.
    h = list(flow.request.headers.fields)
    random.shuffle(h)
    flow.request.headers.fields = tuple(h)

See the mitmproxy documentation on netlib.http.Headers for more details.

There are tons of way to reorder them as you wish:

def reorder(headers, header_order=["Host","User-Agent","Accept"]):
    lines = []
    for name in header_order:  # add existing headers in the specified order
        if name in headers:
            lines.extend(headers.get_all(name))
            del headers[name]
    lines.extend(headers.fields)  # all other headers
    return lines
request.headers.fields = reorder(request.headers)
Community
  • 1
  • 1
Maximilian Hils
  • 6,309
  • 3
  • 27
  • 46
  • Thanks for this! But I've edited my question to be more specific (What if I want to order the headers, exactly as I want them?) I guess [this post](http://stackoverflow.com/questions/31205415/how-to-capture-http-request-response-headers-with-mitmproxy?rq=1) might be a good start? – Tux May 20 '16 at 18:49
  • `headers.fields` is just the list of headers as they will be sent on the wire, you can rearrange them as you wish. I added a small example above. – Maximilian Hils May 20 '16 at 20:48
  • Thanks Maximilian, I'm gonna try your piece of code, this week-end. Do you think I can save your script as-is (obviously after adding more headers) into a .py file, and it will be ready to be "loaded" into MITMproxy? Anything else needed? (I say this because, I'm a total noob, when it comes to Python) – Tux May 21 '16 at 01:28
  • `NameError: name 'request' is not defined` : This is the error message I get, when I try to load this mini-script. Perhaps we're missing something here? I am on Python 3.5.1 – Tux May 23 '16 at 18:06
  • Your help would be very appreciated... Should I add an import line or a "from" line at the beginning of the script? – Tux May 24 '16 at 05:13
  • How to integrate the mitmproxy with the browser? By defining a proxy to the browser and routing the network through it? Is there a way to change the order of the headers by creating a custom browser extension instead of a proxy? – Nathan B Sep 25 '16 at 11:46