Back to writing

Curious adventures

Nov 16, 20258 min read
hackingsecurity
Curious adventures

A lot of my favourite afternoons have started with a quiet "I wonder if...". A screwdriver, an open devtools tab, a print() somewhere it didn't belong. Here are three of them.

1. The lift that took voice commands

The lift in my building had a panel like every other lift — a column of buttons, a tiny 7-segment display ticking through floor numbers as the cabin moved. Once it was open, the electronics inside were friendly and unhurried. A shift register clocking out segments to drive the display. A handful of buttons wired straight into the controller. Nothing exotic.

There were two small openings to play with:

A small board went in with a microcontroller, a relay, and a Wi-Fi link to my home automation server. Node-RED stitched the rest together: a voice intent on a Google Home maps to "close the relay for 200 ms," the floor decoder watches the shift register, and when the digits land on my floor the speaker announces that the cabin's arrived.

The bit that made me smile most was a small parking trick. Holding the call button keeps the lift on that floor — it won't drift back to the lobby while you're still hunting for your keys. So the relay stays closed after arrival, and the moment someone physically presses the call button, the board sees the contention, releases the relay, and normal service resumes. From the outside, the lift behaves like any other lift.

Lift control panel with the cover removed
The custom PCB that sits inside the lift control panel
Node-RED flow tying voice intent, relay, and floor decoder
The Google Home speaker used for arrival announcements

2. The homework that called home

A graduate course I took asked us to submit Python scripts. The scripts were meant to ingest a dataset, run an LLM-assisted analysis, and produce a result. The grader was a server: it ran each student's script, an LLM judge looked at the output, and scores landed in a CSV.

The grader didn't sandbox network egress. My submission did the assignment — and, on import, fetched a small bootstrapper from a GitHub gist that opened a reverse shell over an ngrok tunnel. So while the judge was scoring my output, there was a quiet shell on the grading box too.

The professor wrote a thorough post-mortem afterwards, which is much better read in his words than mine: A post-mortem of hacking automated project evaluation.


3. The teamId that opened a kingdom

I was poking around a YC-backed startup's product with devtools open, in the way one does with a new product.

The product had a "share" feature — you share a thing, someone opens the link, they see it. On page load the client fetched a teamId on its way to rendering the shared resource. Pretty harmless, right?

I tried that same teamId against the endpoint the product used elsewhere to issue an invite to join a team. To my surprise, instead of a 403, the request was accepted by the endpoint and returned an invite code.

That on its own was already a soft spot — a share link could become a seat on the team behind it. The reason it mattered was what the product was. It was a dev tool, and teams had stored API secrets. The team I'd just joined had, among other things:

The Vercel token reached their projects, environment variables across every deployment, and source dumps of the deployed code. The Supabase service key reached their database, end to end.

I wrote it up and sent it to the founders, who were lovely about it and patched things shortly after.

Redacted screenshot of the disclosure thread with the founders
Redacted screenshot of the disclosure thread with the founders

Three different systems, three "I wonder if..." moments. What I keep coming back to is the quiet pleasure of noticing the gap between what a system is doing and what it thinks it's doing — a shift register cheerfully broadcasting the floor, a grader happy to make outbound calls, an invite endpoint friendly enough to take a stranger's teamId.

It's a nice way to learn how things actually work. Also, occasionally, a nice way to call a lift.