(I am aware that security via obscurity is not recommended).
I am trying to hide the fact that I am using Wordpress. This post is helpful, but it only addresses the content (sort of). I am interested in having the following occur:
User tries to access any url with
wp*
as a substring via their browser.Result: Redirected to 404 page.
Blog user/administrator knows in order to login they should go to
http://example.com/blogin/
.Result: apache redirects them to
http://example.com/wp-admin/
.If a user tries to directly access
wp-admin
from their browser they get sent to #1.Result: Redirected to 404 page.
Things I've done so far
I noticed for a default install of WordPress that I could access any of the
wp*
files in the (relative) root directory of the WP install. Specificallywp-settings.php
was problematic because it gave away information about my set-up. If a user accessed it, it would spew some PHP errors and reveal part of the directory structure. I edited my php.ini file to turndisplay_errors
off. Now accessinghttp://example.com/wp-settngs.php
brings up a blank page.This in itself isn't ideal because it reveals that
wp-settings.php
exists. In fact, accessing all the differentwp*
files is possible (with different results). I then put the following in my htaccess file:RewriteEngine On
RewriteBase /
RewriteCond %{PATH_INFO} wp* [NC]
RewriteRule .* - [F]This worked great! Anything with a
wp*
was routed to my custom 404 page. But now I can't access my admin page.I tried to insert this line into the above code:
RewriteRule ^blogin wp-admin [NC,R,L]
. It was supposed to be right afterRewriteBase
but this didn't work.I tried to do a:
Order Allow, Deny
Allow from example.com
Deny from allhoping that a referer from my site (via the rewrite of the rule) would be able to access wp-admin, but not someone from outside. This didn't work either. apache complained that you can't use this directive from htaccess.
I've read the apache documentation; I understand the concepts, theoretically, but I need some practical help.
EDIT: I'm looking for a solution that uses .htaccess instead of httpd.conf since my particular setup makes using httpd.conf inconsistent.
Answer
TLDR; It is not possible to obscure WordPress by only using directives in your .htaccess file.
Now cometh a tale of woe and horror. Our friend, fbh was right about the difficulty in hiding WordPress, it be not for yellow-bellied cowards. Arr! Here be the details of this (mis)adventure. Ye be warned!
Motivation
I'm one of those guys that likes things perfect. I will spend waste time over-engineering something to be the 'right way'. One of things I didn't like about the default WordPress setup was that a user could type in http://ex.com/wp-settings.php and then all this php jargon would spew all over the place. I eventually was able to turn off errors via PHP but that led to a greater desire to only have things that made since be locatable resources from the server...and that everything else would be 404/3'ified to our custom search page. After that I got this idea that I'd like to completely hide the underlying framework (i.e. WP)... anyways... if you want to hide WP it's possible. But it's really hard.
Steps to your doom
Modify your PHP ini settings appropriately. (i.e. turn display errors off) You might think this is unnecessary because if we're using .htaccess to reroute things, folks won't see errors because they can't access the error causing resources (I'm looking at you
wp-settings.php
). But errors could occur in displayed pages, so you definitely want them off. Just becauseWP_*
directives are set doesn't necessarily mean that things will work the way you think they will. I found that on my server I had to set the display_errors to false FIRST, because WP_DISPLAY_ERRORS assumed that the default setting was false.Controlling PHP ini settings may be something as simple as putting a directive in your .htaccess file. Or, in my case, as complicated as creating a CGI handler and then putting a php.ini file there. YMMV depending on your set-up.
Remove all access to files/directories with
wp-
prefix. The idea is that your WP deployment is about your content, not about WP (unless it's specifically focused on WP). It doesn't make sense for people to want to see what http;//ex.com/wp-cron.php has... unless they're up to no-good. I accomplished this via this:# If the resource requested is a `wp-*` file or directory, poop to a 403.
RewriteCond %{REQUEST_FILENAME} wp-.*$ [NC]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_FILENAME} -f [NC,OR]
RewriteCond %{REQUEST_FILENAME} -d [NC]
RewriteRule .* - [F,L]Learn how to just pass through mordor By removing all access to
wp-*
you can no longer gain access to the administrative part of WP. That really sucks. In addition to that downer, you've just realized that you don't know whatRewriteCond %{ENV:REDIRECT_STATUS} ^$
really does. Well, what I tried to do is to give myself a 'secret' backdoor to the WP admin page. I used this code:# If the resource requested is 'mordor' (with or without an ending
# slash) do a URL rewrite to `wp-login.php`.
RewriteCond %{REQUEST_URI} mordor/?$ [NC]
RewriteRule mordor/?$ /wp-login.php [NC,L]So the URL: http://ex.com/mordor should bring us to the login page. The reason why we had the
REDIRECT
line in the step above is that since this URL gets rewritten to awp-*
URL, we don't want the first rewrite rule to get it. Since it's being redirected internally,REDIRECT_STATUS
will be set correctly and it won't push us to 403/4 land.Remove wp-content Wordpress.stackexchange has a great article on removing wp-content. You have to redefine some WP constants and that pretty much works. You also have to redirect all accesses from
wp-content
to 'whatever-content`. This probably won't be an issue if this is a clean deployment. If you're modifying a pre-existing deployment you'll have to do some extra stuff.Rewrite URLs to wp-content optional
RewriteRule (.*)(wp-content)(.*) $1whatever-content$3 [NC,R,L]
. This goes in your .htaccess file. If your user tries to access some old content via awp-content
URL, it will get redirected here.Grep and replace all references to wp-content in your DB optional. You still have
wp-content
in your database. If you want to WP free you need to get rid of that stuff. I exported/mysql dumped my database, did a search and replace on thewp-content
string to the new string. You might say... why do I have to do this if apache will rewrite my URLs? The problem is that the source code will contain these references so if you're really interested in obscuring WordPress, you need to do this. Note: At this point I should've just stopped and accepted the reality that this wasn't going to work. But I wanted Mr. T to pity me.Replace all references to
wp-includes
andwp-admin
in the source. A lot of the WordPress functionality depends on these two directories:wp-includes
andwp-admin
. This means these directory names are hardcoded in the source code. This means that you would have to create new directories (since PHP uses the underlying OS file system, not apache) to access these and then WRITES THESE OUT into the emitted html. This is just way too much trouble. I quickly gave up and went to the bathroom to take a poop.
Lesson
Sure, I could've just read http://codex.wordpress.org/Hardening_WordPress and followed those steps. But I wanted the perfect site. Now I just want all those hours back. The biggest thing that prevented me from stopping was that I didn't read anywhere on the internet that this was a lot of work and almost impossible to do. Instead I read of people trying to do it with no sense of if they were successful or not. So, to my past self, whom I will send this to via Apple's Time Machine, please don't try and obscure WordPress. It's not worth it.
No comments:
Post a Comment