Programming

The earliest memory I have of ‘programming’ is in the early/mid 90s when my father brought home a computer from work. We could play games on it … so of course I took the spreadsheet program he used (LOTUS 123, did I date myself with that?) and tried to modify it to print out a helpful message for him. It … halfway worked? At least I could undo it so he could get back to work…

After that, I picked up programming for real in QBASIC (I still have a few of those programs lying around), got my own (junky) Linux desktop from my cousin, tried to learn VBasic (without a Windows machine), and eventually made it to high school… In college, I studied computer science and mathematics, mostly programming in Java/.NET, although with a bit of everything in the mix. A few of my oldest programming posts on this blog are from that time.

After that, on to grad school! Originally, I was going to study computational linguistics, but that fell through. Then programming languages (the school’s specialty). And finally I ended up studying censorship and computer security… before taking a hard turn into the private sector to follow my PhD advisor.

Since then, I’ve worked in the computer security space at a couple of different companies. Some don’t exist any more, some you’ve probably heard of. I still program for fun too, and not just in security.

But really, I still have a habit of doing a little bit of everything. Whatever seems interesting at the time!


All posts

Recent posts

Using CSP unsafe-hashes

So here’s a fun one: how does the unsafe-hashes directive in a content security police work?

In a perfect world, you don’t need it. You can write a CSP with a minimal script-src policy, including only scripts from your own domains (self) or a list of specific other scripts or at worst domains.

But sometimes real life (and third party libraries) get in the way.

It starts with inline scripts. So you have to add unsafe-inline. But there’s a better way to do that: CSP nonces. Specify a randomly generated (per request) nonce in the CSP header and then apply that same nonce to every script tag. Voila. Better.

The problem: inline JavaScript events

But what about something like this:

<button onClick="doSomething();">

Well, you might say, don’t do that. Write it as a script:

<button id="doSomethinger">

<script nonce="correctHorseBatteryStable">
document.getElementById("doSomethinger").addEventListener("click", function() {
  doSomething();
});
</script>

But like I said–third parties scripts can be imperfect. And sometimes, they just insist on embedding their own event handlers inline.

A solution: unsafe-hashes

Enter: unsafe-hashes.

Basically, you can add this to your CSP:

script-src 'unsafe-hashes' 'sha256-44558f2c36efd8163eac2903cec13ed1fafcca51abd91d9f696321ab895f1107'

This tells the browser that you are allowed to have event listeners directly on HTML elements… so long as the content of the JavaScript hashes exactly to any hash listed as an unsafe-hash:

$ echo -n "doSomething();" | sha256

44558f2c36efd8163eac2903cec13ed1fafcca51abd91d9f696321ab895f1107

It gets worse: dynamically generated JavaScript

There is, however, one problem with this that does come up unfortunately often. If you’re already dealing with third parties not doing things you wish they would, well then you have to deal with fun code like this:

<?php
foreach ($buttonIds as $buttonId) {
    echo '<button onclick="doSomething(' . $buttonId . ');">Button ' . $buttonId . '</button>' . PHP_EOL;
}
?>

Unfortunately… that completely blows up the CSP. Because…

$ echo -n "doSomething(1);" | sha256
2ef899c15aae95711855a45a5bb93c55363162e0e75e295aad4f189f20323d7c

$ echo -n "doSomething(5);" | sha256
0e03bb385169b89c95eb62659f50604ffb8283154bd58ab8cc7e692c4b5c05a3

$ echo -n "doSomething(42);" | sha256
4d9691449db6740ee19207c5bb52361eb97e18f06352ed400f83ae7caee270da

Just hashes doing hash things there. So basically, you have to be able to dynamically generate your CSP on the fly, including all of the hashes of all of the functions and with each of their arguments that are either possible or (even better) actually used.

And this isn’t fun at all.

Now, you might say: but you can do something like this:

<?php
foreach ($buttonIds as $buttonId) {
  echo '<button data-id="$buttonId" onclick="doSomething(this.dataset.id);">'
}
?>

After all

$ echo -n "doSomething(this.dataset.id);" | sha256

d2ecabb98b1bb7cc81cd75d43dcb7bac08ce31055339920976cb92aa2f5dd2f5

Only one hash!

But if you have that much control… then why are you using inline JavaScript in the first place?

Is it safe?

Is this safe?

No. It’s called unsafe-* for a reason. An attacker that controls input can theoretically take any of the hashed functions you’re including (like submitPayment…) and inject them in places they shouldn’t be. And heck, if you manage to find a SHA-256 hash collision? Well, then you have far more interesting things to do with that then attacking some site that found themselves force to used unsafe-hashes

But it’s better than unsafe-inline without nonces which allows arbitrary inline scripts. And unfortunately, there’s no way to actually use nonces with inline scripts.

And while a perfectly secure system would be the best case, it’s absolutely better to do as much as you can to secure a system rather than doing nothing waiting for the perfect solution to become possible.

Onward!

read more...


Building a virtual CPU from NAND gates up

Over the past couple of weeks, I’ve spent entirely longer than I probably should have falling down the rabbit hole that is the game Turing Complete.

In a nutshell, you start with basically nothing, build up simple logic gates, create memory cells and 1-bit addition, build that into 8-bit math and logic, read instructions RAM, implement loops, and function calls (in hardware!), and eventually use your very own custom built CPU to solve a few programming challenges.

read more...


Parsing PEM Certificates & ASN.1 in Javascript

I recently had a conversation about parsing HTTPS/TLS/etc certificates client side (so that various values could be compared). There are, of course, libraries for that, but where’s the fun in that? Let’s dig in ourselves!

I thought of course it would be a well specified format and it wouldn’t take more than a few minutes to parse… right?

Right?

read more...


Solving Woodworm

Woodworm is a cute little PICO-8 puzzle game about a cute little worm… that eats wood. You can play it for free right now right here!

The goal is to turn this:

Level 1, before solving

Into this:

Level 1, after solving

There are a few rules to keep in mind:

  • The block (and the worm) are affected by gravity

  • The block can be split by into multiple pieces by eating it completely apart

    Demonstrating gravity

  • The worm can crawl up the side of blocks, so long as two (consecutive) segments of the worm are touching walls

    Demonstrating climbing

And that’s really it.

So let’s solve it!

read more...


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='

read more...


Freshly (Frosted) Solved

And so it begins.

Freshly Frosted

It’s a cute little puzzle game about making a donut factory.

It’s a lot like Solving Cosmic Express in that it’s a ‘puzzle on rails’, you are basically routing around the grid from source to target. In the way, we have to go to certain tiles in a certain order (in this case, to apply toppings to our donuts).

The first level

Let’s do it!

read more...


AoC 2024 Day 25: Christmas Lockpickinator

Source: Day 25: Code Chronicle

Full solution for today (spoilers!).

Part 1

You are given a series of locks and keys (see below). How many unique (lock, key) are there that do not overlap (they do not have to fit perfectly).

A lock starts from the top. The entire top row is # and the entire bottom row is ..

#####
.####
.####
.####
.#.#.
.#...
.....

A key is the opposite:

.....
.....
.....
#....
#.#..
#.#.#
#####

read more...


AoC 2024 Day 23: LAN Partinator

Source: Day 23: LAN Party

Full solution for today (spoilers!).

Part 1

You are given the edges of an undirected graph. Count how many complete subgraphs of size three exist that contain one or more starting with the letter t.

Aside: Games with local (but not hotseat) multiplayer have gotten rather rarer over the years… how many people still know what a LAN party is/was?

read more...