A quick mitmproxy setup

Another quick thing that I set up for the first time in a long time. It’s honestly as much a note for myself as anything, but perhaps you’ll find it useful too.

The problem: We were having intermittent issues with a content security policy. One of the warnings that cropped up was the inclusion of 'inline-speculation-rules' in the policy. This is currently only supported in Chrome and the issue was only appearing in Firefox. I could of course go through the effort of removing the header locally and testing–but what if I could lie to the browser and change the header on the fly?

Well, for that, you have a number of options. Burp Suite, ZAP, Charles Proxy. Many more, I’m sure. Any of these can modify traffic on the fly like that, but they’ll all designed for so much more than that, making them a bit unwieldy. What I really wanted was something that was a whole lot smaller and did only this one thing (or could be at least configured as such)

Enter mitmproxy. I’ve used it before, but never quite like this. As the name suggests, mitmproxy is designed to man-in-the-middle yourself as a proxy–feed all web requests through it and it can read requests, modify and forward (or block them), read responses, modify or replace them entirely, and all so much more.

Exactly what I needed!

read more...


WebCrypto SHA-256 HMAC

A quick random thing I learned that I found helpful (and you might too!):

async function hmac(text, secret) {
    let enc = new TextEncoder("utf-8");
    let algorithm = { name: "HMAC", hash: "SHA-256" };
    
    let key = await crypto.subtle.importKey("raw", enc.encode(secret), algorithm, false, ["sign", "verify"]);
    let signature = await crypto.subtle.sign(algorithm.name, key, enc.encode(text));
    let digest = btoa(String.fromCharCode(...new Uint8Array(signature)));

    return digest;
}

This is a function that uses the Web Crypto API to calculate a SHA-256 HMAC of a string given a secret value.

I mostly worked this out so that I could figure out how exactly TextEncoder worked, along with importKey (to turn a secret into proper key material) and also how to convert that back into a hex digest.

>> await hmac("lorem ipsum", "super secret")
"qArFX93Zi83ccIayhYnuFDpd4pk3eB4rZYDvNteobSU="

>> await hmac("lorem ipsum doler sit amet", "super secret")
"klTAioH5nNkguNhU2YcJshaZZtJW9DEb+MTqz4NWq8E="

>> await hmac("lorem ipsum", "even more super secret!")
"RoQLg2uz5KWLMJM72VExH5gZOls5bdZZyzHi678eDWs=" 

>> await hmac("lorem ipsum", "super secret")
"qArFX93Zi83ccIayhYnuFDpd4pk3eB4rZYDvNteobSU="

Disclaimer: This totally counts as rolling your own crypto. Don’t do this unless you know what you’re doing. 😄

Disclaimer disclaimer: I only rarely know what I’m doing. 😄 😄

Also, for what it’s worth, this is equivalent to the Python standard libraries’ hmac + base64 :

>>> base64.b64encode(hmac.digest(b'super secret', b'lorem ipsum', 'SHA256')).decode()
'qArFX93Zi83ccIayhYnuFDpd4pk3eB4rZYDvNteobSU='