they're on to us

posted by tom / August 25, 2005 /

It's been fun basking in blogospheric attention for an HTML hack that could be performed by any number of middle-schoolers. But, sadly, a commenter has pointed out that the zoo is on to us -- the butterstick submission form no longer works. I'll try to have another look at it tonight, but it's likely that there's nothing to be done. On the upside, this means that there probably were votes labeled "butterstick" making their way into the zoo database. Which is pretty great.

Catherine suggested explaining the hack, so for those interested, a rundown of the relevant webdev principles is behind the cut. The rest of you should start thinking about the next step in fomenting the Pale Yellow Revolution.

I'll try to keep this short. Imagine a classroom election. There are two ways to track votes. One is to keep a tally -- imagine making a check on a blackboard for every vote under the appropriate candidate's name. You can do this in a database, but it's a bad idea, because if someone starts stuffing the ballot box you won't be able to filter out the bad votes by their identifying characteristics (in our classroom example, handwriting; on the internet, IP address and submission time).

So the alternative is to keep a record of each vote. Each record contains identifying characteristics like IP address and an indication of who the vote was for. Because you'll end up with a lot of records in this system, you should try to keep them small. When voting is over, you throw out the bad ones, then count them up.

It was clear from the form's HTML that someone wasn't writing very good code. It looked kind of like this:

<INPUT TYPE="radio" NAME="panda" VALUE="Qi Gon Jin"/> Qi Gon Jin: Means 'Righteous Child Bathed in the Blood of the Debauched West'
<INPUT TYPE="submit"/>

Sending a value of "Qi Gon Jin" implies that the form's author is dumb, though. Here's the possible things a web server can do with that submitted data:

  1. Add another tic mark to the "Qi Gon Jin" column. This is the chalkboard method, and as mentioned, is vulnerable to ballot-stuffing.
  2. Record a single, separate vote record for "Qi Gon Jin". This is dumb because "Qi Gon Jin" takes up many times more space than a simple number would. It'd be much more efficient to assign a key to each candidate — say, "1 = Qi Gon Jin; 2 = Chun Li; 3 = whatever". Of course, you could still do this by...
  3. Looking up the key that corresponds to "Qi Gon Jin" in the database, then recording a vote for that key. But this means an extra trip to the database, which is inefficient. Still, alternately you could...
  4. Put the key-to-name relationship in the code that handles storing the form. But this is called "hardcoding" the relationship, and is frowned upon because it means that changing the candidates requires changing data both in the web page and in the database.

So something was amiss, and, knowing the ways of lazy and or/incompetent programmers from personal experience, I suspected #2. As a result I had a hunch I could just add an extra radio button. I did and it seemed to work. The code looked like this:

<INPUT TYPE="radio" NAME="panda" VALUE="Qi Gon Jin"/> Qi Gon Jin: Means 'Righteous Child Bathed in the Blood of the Debauched West'
<INPUT TYPE="radio" NAME="panda" VALUE="Butterstick"/> Butterstick: FONZ is for Fascists
<INPUT TYPE="submit"/>

What's the right way to code a simple survey app, you ask? I'm glad you're so interested. The answer is to generate the original form from the list of possible candidates in the database, putting the key for each candidate in the radio button HTML instead of the name of the candidate. Then have your server accept and record whatever gets submitted, just as they were doing (if space was a concern, they could set up a simple script to clear out entries with invalid keys once every few hours). I would still be free to submit keys for non-existent candidates, but the word "butterstick" wouldn't show up in the database, the key wouldn't correspond to anything, and the whole exercise would be much less interesting. To me, anyway. I trust I've already made it plenty uninteresting to you.

Anyway, I don't blame them for doing it the way they did. A simple voting form is not exactly a complex engineering task; the odds of running out of space in the database or maxing out the server with unnecessary database processing are both very low. But still — it's not much more work to do things the right way. They thought they could get away with half-assing it; if their cause weren't so blatantly evil and repressive, they probably would have been right.

Post A Comment


Email Address



Remember info?

Google Analytics