Last week, I ran a giveaway which, because of a variety of reasons, I had to cancel and declare “null & void”. While I won’t go into the details, I did want to bring some actions to the forefront, especially if you are using the WordPress plugin called “WP-Polls” which is a great plugin that provides users with the ability to vote on questions and tally the results in graphs.
WP-Polls is currently the most popular polling and voting plugin with the WordPress “Extend” section with over 370,000 downloads. It is great for general polling of audiences. You can embed these polls into individual articles, in your sidebar or have them appear automatically in a dedicated page. The developer, LesterChan.net, has developed many great WordPress plugins of varying functionality. WP-Polls is described: “Adds an AJAX poll system to your WordPress blog. You can easily include a poll into your WordPress’s blog post/page. WP-Polls is extremely customizable via templates and css styles and there are tons of options for you to choose to ensure that WP-Polls runs the way you wanted. It now supports multiple selection of answers.“
As this was the most popular voting and polling plugin on WordPress, I thought that it would be good to do the “popular vote” for my computer giveaway. I was very wrong. Using a simply script, WP-Polls can be exploited and voting results can be manipulated. I have all the respect for the developer of this plugin as I regularly use other ones of his. My reasoning for posting this is to ensure that this exploit is highlighted so that the developer can change it and to inform other bloggers about the risks of using it.
I am posting the entire exploit below to bring light to it so that awareness can be spread and the hole can be fixed. This is from a forum post on the Critical Security site. The poster introduces the script:
This is a function I’ve been writing, to basically brute-force my votes onto a WordPress ‘wp_polls’ poll. wp_polls is a plugin for WordPress, and the admin makes a poll with options, and can set restrictions on how many times a unique user can vote. I followed the theory and the clock work behind it, and see that it is only blocking you by IP Address (which, I will explain in a second), and cookies.
Apparently, for some unknown reason, WordPress checks the X-Forwarded-For header, before it does the REMOTE_ADDR. With this in mind, we can write a script to send a uniquely spoofed X-Forwarded-For header, along with our POST data to the script, of which poll is being voted on (poll_id) and which option is being selected (poll_(poll_id)).
I basically dissected the HTML form data to determine what data had to be sent via POST, and collect the cookies, but don’t use them again. I think the function turned out rather well… you can check it out and use it if you like. Basically, I can enter all of the poll_id’s and which option is being voted on, and specify how many times I want the function to vote on a given option (while loop).
I started seeing this script in action on my site when a bunch of votes were being logged within the 1.0.x.x to 1.x.x.x range (typically a range reserved and not used as a public IP address). Also, a majority of the “valid” votes typically had the IP address and the associated node or computer name of the location (e.x., 123.456.789.012 computerabc.sbc.net). The “invalid” votes had numbers within the name field (123.456.789.012 123.456.789.012) and there were a huge number of votes of this type.
Here is the full exploit code (as an image). I am not posting this so that it can be abused, I’m just hoping that either the developer (lesterchan) or others will correct the poll plugin to prevent this from happening:
Anyway, because of this script, there were many (several thousand) invalid votes that logged in my voting giveaway. Because of that as well as the fact that my site suffered a Denial of Service attack which prevented people from voting during the pre-defined voting period, I rendered the giveaway as null & void.
I also used another one of LesterChan’s plugins called WP-Ban to help mitigate some of the issues that I was having. I put in ranges of IP numbers that needed to be blocked (e.g., those private IP ranges). The plugin description: “Ban users by IP, IP Range, host name, user agent and referer url from visiting your WordPress’s blog. It will display a custom ban message when the banned IP, IP range, host name, user agent or referer url tries to visit you blog. You can also exclude certain IPs from being banned. There will be statistics recordered on how many times they attemp to visit your blog. It allows wildcard matching too.” I also recommend the WP-DBManager for backing up and restoring your databases.
HTD says: If you are going to use a poll to give away something or decide something critical, be sure that you use a 3rd party (not a WordPress plugin) to manage the process.