Rigging PollDaddy

One of my best friends siblings was in a poll competition on a popular blog. He was doing okay, but he wasn't close to the lead. I thought I'd see if it was possible to boost his numbers a bit.

The poll in question was administered by PollDaddy. I blurred out the data, but this is what the embedded poll form looks like:

Form Image

The first step was to find the URL that it was embedding from. That way it removes all of the other loading factors of the blog page. Luckily, in the HTML right after the div containing the form was a <noscript> element.

<noscript>
  <a href="http://polldaddy.com/poll/(poll_#)/">Poll question?</a> 
</noscript>

I noted down the poll #, and went to that URL. The next step was to submit the form, and look at the data in Fiddler (a great tool for viewing web interactions). I noticed that it was requesting a URL, of this form:

    /vote.php?va=30&pt=0&r=0&p=(poll #)&a=(answer #)%2C&o=&t=(random)&token=(random token)&pz=(random code)

The "answer #" was easily extracted by looking at the value for that checkbox. The rest of the information I noticed was stored in the "Vote" button under the "data-vote" information...except for "pz", which was weirdly in a hidden input field. The next step was to start up a Python script to spam the hell out of it. I set up a Python script to use requests to request the original page, scrape the "data-vote" information into an array, scrape the "pz" value from the hidden input, and construct the URL. Then, I had it request that URL. It immediately ran into a problem.

When you submit the form normally, you're redirected to /poll/(poll #)/?view=results&msg=voted. With the script, however, it was redirecting to /poll/(poll #)/?view=results&msg=revoted&stokenFound. So something was wrong. I extracted all of the headers from the valid request, and forced Python to use that header. Now it went through! I was getting somewhere.

Unfortunately, after ~20 requests, it would stop working again. The 'revoted' message would show up, and no further votes would be made. I figured that it was probably stopping my IP because of the speed of requests, and looked into getting Python's 'requests' module to fake its IP address. After ~30 mins of no success, on a whim I tried running the script again, and it was working! So that meant that the server was just blocking for a while before allowing more votes. After some trial and error, I found that making it sleep for 3 seconds after every request, and then sleeping for 60 seconds once it was blocked was a good point. I didn't want to harass their servers, and 60 seconds seemed like the time to allow it back in. That averages out to 1 vote every 5.4 seconds.

If you want to look at the script, or use it yourself, it is up here on my GitHub.

Over 4.5 hours, he rose 3000 votes, and went on to win. PollDaddy's a great solution for casual polls, but don't use it if you don't want scripts to vote easily and quickly.

29 comments