This prompted the somewhat weird thought:
Has (or should?) anyone use github to actually run an organization's board?
It's not quite set up to do so, but it does seem surprisingly close – I could imagine having founding documents on an organization's bylaws, which board members can propose, review, and approve. You could have rules on PR merging that include "requires a 2/3 majority of members of the board."
I've been playing a game of Nomic, where rules are interpreted by a script we edit instead of by the players. This morning Chelsea won our second game of Nomic with a timing attack:
Our game was set to use random numbers to figure out if someone had won. Effectively, each point you earn should give you an additional 1/100000th chance of winning. The source of randomness was python's random.random(), which was fine.
I had written a PR (#98 to move us to using something derived from the hash of the most recent merge commit on master. I was intending for this to be a timing attack: the merge commit should be predictable entirely from its contents and the current time.
The idea is, I can test for each upcoming timestamp whether there's hash that would end on me winning. A very hacky way to get git to think it's in the future is just to set your local clock fast:
Unfortunately, when I tested trying to exploit this I found that GitHub signs the merge commits it makes. For example:
This meant there was some information in the hash that I couldn't control, and this wasn't going to work.
At this point the smart thing to do would have been to delete the PR: if I know it's dodgy but I can't exploit it then I shouldn't let anyone else take that opportunity! But instead I figured "I guess it's safe, then -- nice to have reproducible random numbers" and went to bed.
The next morning I saw that Chelsea had won, and was surprised by the winning commit:
No signature! Chelsea had noticed that GitHub allows making a local merge and then pushing that up. You can generate a local merge commit for an PR with an appropriate hash by tweaking the timestamp git reads (or waiting for exactly the right time) and then push the merge commit up when you're ready (her summary).
So Chelsea prepared a vulnerable local commit, approved the PR with a cheeky message, and pushed it up. GitHub accepted the merge, Travis calculated a random number of 0.00005 which was in Chelsea's win-range, and we had a winner!
It turns out, however, that a merge commit pushed from the command line isn't checked very thoroughly, and this on its own would have been enough to win. For example, I created a PR (#103) that docked myself a point, which is allowed to be merged without additional approval as a points transfer. Then, once Travis passed it, I merged it from the command line with:
You can see that this let me include extra changes in my merge commit that gave me 100,000 points. Even though the extra change wasn't in the PR that github ran tests on, I could still push the merge commit up:
Which made Travis call me a winner, though I'm not since Chelsea had already won: