Nitzan from Daylight hacked our vibe-coded minesweeper
Look, we obviously vibe coded MetalBear Minesweeper. We may have not spent too much time looking for security holes. In fact, our whole motivation may have had more to do with marketing than building a fair ranking of who’s actually the best at minesweeper.
Alas, we forgot we have customers in cybersecurity. Nitzan from Daylight easily tore our code wide open, then like the ethical hacker that she is, offered to disclose the vulnerabilities for the modest price of having her name on a banner on the Minesweeper page. Done and done.
The bug
Our leaderboard ranks by score, and score is mostly a function of how fast you clear the board. The problem: every input that established how fast, i.e. the per-move timestamps and the total time, came from the player’s browser. The server took the client’s word for it, so you could just send a request saying you cleared expert in 15 seconds, and as long as your move list was internally consistent, we believed you.
Plus, the board is fully determined by a seed we hand the client when the game starts, generated by a PRNG that also lives in the public game.js. So the client always knows where every mine is. “Solving” the board takes no skill and no time: you can generate a perfect winning sequence in code, stamp it with any plausible-looking time, and submit it the instant the game begins. No human beats a bot that clears expert in the minimum allowed time, every single time.
Nitzan is awesome
She sent us a full regression test. It spins up real games against the server and fires three payloads:
- an impossibly-fast clear, which must be rejected;
- a genuinely fast human run, which must be accepted, so we don’t punish good players;
- and the sneaky one: a plausible time claimed, but with zero real time actually elapsed, which must be rejected.
The test literally encodes the definition of “fixed.” It’s a very nice way to tell us our code is broken.
The fix
Stop trusting the client’s clock. The server now records when it issued the seed and measures the real wall-clock time until the submission lands. Claim a 15-second solve when only two seconds actually passed on our side, and you’re rejected: you can’t have played for time that never existed. Legitimate quick players are untouched, because real time genuinely passes while they play. Her test now goes green.
It doesn’t make the game bulletproof. Because the seed still reveals the board, a determined bot could wait out the clock and submit a machine-perfect run. That’s a deeper design question, don’t ship the mine layout to the client, that we’re never going to bother implementing. But the “top the leaderboard in zero seconds from your terminal” hole is closed.
The takeaway
MetalBear Minesweeper is more fair now. Give it a go to maybe win some prizes, then install mirrord for the best prize of all: a super fast dev loop for you and your agents, like Daylight has.
