Tonight, I solved a very old problem in WordPress security among novice users. I will show you how to hide your WordPress admin directory while still being able to use it! When I say “hide,” I mean you can rename the wp-admin folder to whatever you want!
The Code (for people who don’t want to read)
Copy and paste the following into your .htaccess file (located wherever your WordPress folder is) to “rename” your wp-admin folder! If you are having trouble editing your .htaccess file, you should Google around for that as it’s beyond the scope of this article (or post a question in the comments and maybe another person can help).
- Change YOURSECRETWORDHERE to something else. It can be any word you want. Just make sure it’s unique and somewhat long. Make it, like, your pets name or something random. Read this post to understand why this matters.
- Change ADMINFOLDER to the new folder name you want. Letters, numbers, underscores, and dashes only. That ^ in front of it is on purpose. Don’t delete that.
RewriteEngine On
RewriteBase /
##### ABOVE THIS POINT IS ALREADY INSERTED BY WORD PRESS
##### Michi’s code is BELOW #####
RewriteCond %{REQUEST_URI} wp-admin/
RewriteCond %{QUERY_STRING} !YOURSECRETWORDHERE
RewriteRule .*\.php [F,L]
RewriteCond %{QUERY_STRING} !YOURSECRETWORDHERE
RewriteRule ^ADMINFOLDER/(.*) wp-admin/$1?%{QUERY_STRING}&YOURSECRETWORDHERE [L]
##### Michi’s code is ABOVE #####
##### BELOW THIS POINT IS ALREADY INSERTED BY WORD PRESS
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Note: there are a few drawbacks to this hack. Read the bottom of this post for those.
The Explanation
My adventure started when I read a pretty terrible piece of advice that suggested using the .htaccess file to restrict who sees your admin section by IP. Great, so if I’m at work, I can’t login. So if my IP changes, I can’t login. If I’m at Starbucks, I can’t login. That’s retarded. That’s not a solution!
But it’s on the right track. The .htaccess file can do a lot.
Oh, and if any WordPress developers ever read this, please make the word press admin folder be a variable name you can change! It is retarded that it is a hard coded.
The .htaccess file shines best when it is used for URL rewriting rules. For you non-programmers, the next block explains a little about what I just said. If you don’t care, skip it.
It is good for making URLs access files that don’t necessarily exist on the server exactly as they appear in the URL. For example, Digg.com uses URL rewrites to hide file and variable names. So the URL digg.com/videos certainly does not point to a file or folder actually called “videos”. Rather, it probably turns into something like digg.com/somefilename.ext?type=videos. The point is, you can hide what’s actually happening behind the scenes. I hope you get the idea.
Disabling the wp-admin Folder and Creating a Secret Mirror Folder
There are two steps in blocking access to the wp-admin folder. Disabling it is easy, but making it still functional is the hard part. Additionally, there are CSS files and other dependencies in that folder that must still be used. So after disabling it, a condition must be added that makes it only be disabled when appropriate.
RewriteCond %{REQUEST_URI} wp-admin/
RewriteCond %{QUERY_STRING} !YOURSECRETWORDHERE
RewriteRule .*\.php [F,L]
- The first line says “If the word wp-admin is found in the URL…”
- The second line says, “And if the query is missing our password…
- The third line says “And it’s a PHP file… Deny access.”
We’ll get to that password thing in a minute. At this point, if you visit wp-admin/, it will not work. Half way there!
The next part is the guts of it all. We get to set our very own admin folder! I want to call my admin folder “secret_room”. So here’s how the code would look:
RewriteCond %{QUERY_STRING} !YOURSECRETWORDHERE
RewriteRule ^secret_room/(.*) wp-admin/$1?%{QUERY_STRING}&YOURSECRETWORDHERE [L]
This next block is for you technically oriented people:
The first part basically makes sure the rule doesn’t trigger itself later (recursive condition). This is basically saying “if the URL starts with ‘secret_room,’ then replace that part with wp-admin. Then, add in the query string (things after the question mark). Finally, add in the secret word.”
Now, if I go to the folder secret_room/, it will work just like wp-admin used to!
Don’t use “secret_room.” That’s my example. You use whatever folder name you want. Letters, numbers, underscores, and dashes only.
But we’re not done yet. That secret word thing needs to be customized. Why? Well, try this. Go to your blog’s wp-admin folder, but this time, add on “?YOURSECRETWORDHERE” on the end and it will work too (as in, myblog.com/wp-admin/?YOURSECRETWORDHERE)! Curious why? If you’re a little geeky, read the next block. Otherwise, skip it.
Well, this hack works by changing the URL you type in by adding that “secret word” on the end of it. It only does this when someone visits the “secret_room” folder. But it doesn’t add it on when you just type in the wp-admin/ folder (or any other location). Then, when someone is looking at a wp-admin folder, it looks to see if that secret word is in the URL. If you went to the URL by hand, you likely did not type that word in. But the “secret_room” always makes sure the secret word is attached. This is how it distinguishes between visiting wp-admin directly, and visiting it through the mirror folder. Remember that any re-writing of the URL happens behind the scenes, so your browser won’t show you what’s going on.
Since I just gave this same code to about 10,000 people, it’s in your best interest to change your secret word to be unique to you. Note that nobody will ever see it, including you. You will forget what it is, and realistically, it doesn’t matter what the hell you set it to. As long as it’s not the default one I just gave to you. Ideally, it should be long and something highly unlikely to appear in a URL. Try your name, then maybe add your favorite color. I don’t know. Just do something random. Case matters.
Here is what the final .htaccess, ideally, should look like:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} wp-admin/
RewriteCond %{QUERY_STRING} !YOURSECRETWORDHERE
RewriteRule .*\.php [F,L]
RewriteCond %{QUERY_STRING} !YOURSECRETWORDHERE
RewriteRule ^secret_room/(.*) wp-admin/$1?%{QUERY_STRING}&YOURSECRETWORDHERE [L]
# BEGIN WordPress
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
Benefits and Drawbacks to Hiding wp-admin
This hack has its drawbacks.
- The “edit” link on your posts will no longer work. You may want to remove it from your theme.
- The admin link on your side bar will no longer work. You may want to remove it from your theme.
- The standard login link will no longer work. Instead, use a bookmark as it will redirect you back to your hidden login page after you finish logging in.
Note that the first two drawbacks can be addressed by editing wp-includes/link-template.php: line 248 and 263. Change “wp-admin” to your new folder name. However, this hack would need to be re-done if you upgrade WordPress. If you make these hacks, it will only be visible to users who have permission to see these links anyway.
There are a few significant upsides:
- If ever again there is another vulnerability that hits the WordPress wp-admin folder, you are very likely immune.
- Upgrading WordPress doesn’t un-hide the folder. It will persist through upgrades.
Remember, this hack will not protect you from having an insecure admin password. Although, it could protect you from a hacker since he won’t know where to go after successfully logging in (hah!).
Lastly, be careful when doing this. If you type something wrong, you’ll get server errors (I believe error code 500). Make sure you type it in exactly as you see it in these examples first. Then change one part at a time.
Changing the Admin User
One other point I noticed when tightening up my security was the default admin user name. Now, hah, this is assuming they actually brute force my password and then figure out how to get to the admin folder… good luck.
I noticed that I had an admin user account under the login name “admin”. Well, that’s a no-brainer. I went into the database and ran the following query:
UPDATE wpt_users SET user_login = ‘[my new username]‘, user_nicename = ‘[my new username]‘ WHERE wpt_users.ID = 1 LIMIT 1;
That solves another part of the problem. Now hackers have to guess not only my password, but also my username.
In Closing…
If you like what you’ve read, I’d appreciate it if you could Digg/Reddit/Stumble this article.