WordPress Security for the Paranoid Sys Admin

OK, I love my Sys admin. He does not get paid enough to do his job. He has to put up with “users” who have no idea why it is a bad thing to check their MySpace while at work, and will download anything on their computer that is free if it has a flashy web page. Yeah he’s a little sarcastic, a bit caustic, and one might venture to say “anti-social”, but if you know the kind of people he has to deal with you would understand why.

So I got this WordPress thing running on our test server and I got the OK from my awesome Sys Admin to make it public on the web. After management OKed everything, and I was given access to one of the company’s web servers, we had a conversation about security. I knew enough to make him satisfied that I was not incompetent (which means a lot to me) and he said he had looked over the code and had a few concerns. The last thing on his list, after we addressed a few others, was the issue of how to control “where” content could be edited or uploaded from.

“I don’t want anyone who is not in this office to be able to upload, change, or otherwise modify, anything on the system,” he said to me.

“OK,” I respond. “The WordPress Platform wasn’t really designed with that in mind. It was designed for collaboration across multiple locations. Do we need to go with another solution?”

“If you can figure out a way to make it can only be accessible from a specified IP, then no we don’t.”

“OK, I’ll see what I can find.”

So I borrowed books on PHP. I read how-to’s on the internet. I went to book stores and read books (without buying them). I was at a loss until remembered something a professor of mine once said,

“Don’t reinvent the wheel. Chances are some already had put the tools together you need, you just need to figure out how to use them in a way that will benefit you.”
-Professor Bill McCarty, APU School of Business

So I went back to the basics:

  1. WordPress only allows access to the areas that let you change things if you have a login
  2. If uses have a strong password it’s hard to forge access to the system, but not impossible
  3. All the true admin features are controlled by files in the “/wp-admin/” folder
  4. WordPress is basically a gigantic PHP juggernaut
    Problem: While WordPress can manage user permissions, what can you do to prevent access to admin features is someone forges admin access or is able to get a hold of an admin name and password?

    Solution: Create a php code block that checks the IP address of the web client connecting to the WordPress site, and kill the php file being accessed if that does not match the desired IP address(es).

What does that look like:

02//restrict access to this file to an IP Address
03$remip = getenv('REMOTE_ADDR');
04$time = date("d/m/y : H:i:s", time());
05if (($remip != 'ipaddress1') && ($remip != 'ipaddress2')) {
06 error_log($time . ', access from invalid ip: ' . $remip, 0);
07 die();

What does this mean?

Basic programing 101 will teach you that you can create a variable and store data in that variable (also called a memory space). So I created two variables here $remip and $time. By calling the “getenv(‘REMOTE_ADDR’), a php script will ask the client browser what the IP address is of the machine that it is connecting to, so I just stored that as $remip (sort for remember ip address). I’ll come back to the fourth line, because you may not need it for your situation. Line five starts an “IF” statement that (in english) say “If the remembered IP address does not match this address and/or this address, do the following” Line six, I will come back to is a second when I address the time element. Line seven stops the php interpreter from running with no other processes allowed to run.

Add these lines of code to any php script in word press, and the user who tries to access that element of wordpress will get a black white page loaded in the web browser, not the page they clicked to load.

Returning back to that “Paranoid” theme of this post, I presented this solution to my Sys Admin and their response was not the joyful one I was hoping for.

“So how will we know if someone tries to access the system form a website that is not allowed?”

“Well, I assume that this will send an error code to the php compiler, and that would be dumped to the standard sytem log.”

“Have you ever seen the kind of error reports Apache gets when there is a PHP error. I hate PHP. It’s a glorified mark up language, not a program language. The error reporting is crap! I need to know if an attempt was made, and from what IP address, and a time stamp would be nice too, since the Apache log can sometime be out of synch with things.”

“OK, I’ll see what I can do.”

So line 4 creates a variable called “$time” and uses the standard “data” command to format the time as Month, Day, Year, Hours, Minuets, and seconds to store the time the user accessed the file. Then my nightmare really begain, how to format the error report. After hours of searching, and lots of php manual reading, I reached the same conclusion my Sys Admin did, “Error reporting in PHP is CRAP!!!!” It’s so much easier in Perl! So to spare you the time, here is what line six says in english. “Send and error report to web server log that ‘[time the file was accessed] access from invalid ip: [ip address that tried to access file]’ and give the file name to the server that the error occurred in.

Does this end my adventure in security, of course not.

“I like it,” says the Sys Admin. “Generate a clear error report and stops things dead without letting the user know they are being block for a specific reason.”

“I’m glad you like it.”

“So are you really going to enter that code in ever file you need to secure?”

At this point the whole office her the sound of my hand smacking my forehead.

“I’ll see what I can do. It’s php, so that should be easy to roll out.”

So the last nugget I leave you with is this. I did not copy this code into any files. just put this code, all by it’s lonesome, in it’s own php file and saved it in the wp-admin folder of my wordpress install. What I added to every file I wanted to lock down was a line of code that says:

include([file name]);

Now I just have to update one file if I want to change or add address that are allowed.

    Result: If a change is made the the WordPress blog, from an unauthorized location, the attempt will be thwarted and logged on the server.

I made my Sys Admin proud. He really is a cool guy, who is just looking out for what is good for our company. And he pushed me to not settle, but to keep going and learning. Now I’ve got a good working knowledge of PHP, and server side web admin.


~ by trinity777 on November 26, 2008.

3 Responses to “WordPress Security for the Paranoid Sys Admin”

  1. […] WordPress Security for the Paranoid Sys Admin By trinity777 Solution: Create a php code block that checks the IP address of the web client connecting to the WordPress site, and kill the php file being accessed if that does not match the desired IP address(es). What does that look like: … Trinity's World – https://trinity777.wordpress.com/ […]

  2. Hi Tim,

    Thanks for the very informative post! I can definitely make use of the code snippets to lock down wp further, but unfortunately, this does not address the wp-cron problem as that function gets run each time a page is accessed.

    Happy ThanksGiving!


  3. WP-Cron is the bain of a lot of peoples existance. I just wish that the wordpress team would find a way to store the needed cron jobs in the sql database, not as PHP enviornment variables. Then we could modify wp-cron.php to run as a regular system cron and pull the information from the sql database. But…alas, it is not to be. There are a lot of ways around it. Unfortunatly the opinion of the hard core wordpress people you will run into on the forms is that what kind of a service in the right mind is running a server that is not powerfull enough to handel the process. This is in direct confilict with sys admins for that server who’s very job is to manage processes that take up a lot of resources.

    Give it time. I’m sure a better solution will present it’s self for people who are on shared hosting servers. Fortunalty my sys admin is OK with it, becuase the only people permited to run the script are those coming from a select number of IPs, so it cuts down on the useage.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: