Disclaimer: I am NOT a web programmer, nor am I a PHP expert.
In preparation for FRC season, I decided to do some maintenance of the quiz website where I have hosted FRC rules quizzes for the past two years. Apparently Webtester has two(or more) major security holes. I discovered at least 12 different malicious files uploaded, and at least two other major problems on my site. I’m going to document here what I did to fix my copy of Webtester (version 5.1.20101016), since I haven’t really found a better tool for the way I want to host quizzes.
I’m taking two approaches to this: Closing known holes (Google for “WebTester 5.x Multiple Vulnerabilities” to see a few detailed reports), and obfuscating obvious things. At least one of the attacks made an attempt at getting the details of any blog software I use, but I think the randomized table prefix goes a long way in preventing random SQL injection from getting in. This will involve renaming tables, and probably learning a bit of PHP along the way.
Hole #1: The testID field in a test URL allows SQL injection.
For this, I did some research on SQL injection in PHP. it looks like the quickest fix is to sanitize input with mysql_real_escape_string() around any inputs that are used in SQL expressions. This was not fun to implement, because this kind of fault seemed to be all over the place in the code. I eventually got it everywhere obvious, but then noticed that I had broken some functionality… I had to go back and fix this in a few places.
Hole #2: The tinyMCE version used has a totally insecure file uploader utility.
I couldn’t actually find where the normal way to get to this utility was, so I just uninstalled it. Nothing seems to be broken for me. I simply renamed “filemanager” to something else and was sure that there was a blank index file to hide the folder structure. Once I am sure nothing is broken, I might delete the folder entirely.
Hole #3: If they do get some SQL injection to work, the database tables have obvious names.
This took some time, but I wanted to make a way for the tables to have a prefix, like wordpress does. This also helps prevent conflicts with other apps that use obvious table names. For now, I added a custom prefix to includes.php and inserted ” . $table_prefix . ” in every single SQL statement in the entire application (at least 275 of them by my current count). Tedious, but worth it, I think. Doing this task alone makes me want to rewrite the whole thing from scratch as a Ruby On Rails app.
While poking around in the code, I noticed a few other items that were quick to fix. Search for the following and fix as needed to clean up your copy.
- Search for Erorr and correct to Error
- Search for if(NODONE) (the second of two places in grade.php) and correct the preceding <? to <?php
I plan to have the quiz site back up in time for next year’s quiz, which is about 6 weeks away. I’ll try to keep a close eye on hacking attempts.